锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C#开源英语 / 以线程安全方式访问Windows窗体控件的RS232技术
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

锐英源精品开源心得,转载请注明:“锐英源www.wisestudy.cn,孙老师作品,电话13803810136。”需要全文内容也请联系孙老师。

RS232 using thread-safe calls to Windows Forms controls 以线程安全方式访问Windows窗体控件的RS232技术

Introduction介绍

As RS-232 is still used often in industrial applications, Microsoft has added the SerialPort class to its .NET 2.0 framework. 由于RS-232仍然经常使用在工业应用中,微软向.NET 2.0框架增加了SerialPort类。
When communicating with a Windows Forms application and displaying the received data, for instance in a TextBox, the problem occurs, that the serial port and the textbox are using different threads. MSDN describes a way to solve this problem. 当和一个Windows窗体应用程序通信,并显示接收到的数据,例如在文本框,有问题会出现,即,串行端口和文本框使用不同的线程。MSDN描述了一个方式来解决这个问题。
As an example of how to apply all this, using Visual C#, a small application has been built: 运用这一技术的例子示范,已建成一个小型应用程序:
例子示范
First of all, you have to place, from the Toolbox=>Components, a SerialPort onto the Form. 首先,你必须从“工具箱”=>“组件”拖一个 SerialPort到窗体上。
Then, in the Properties, set the serial port to 9600,8N1 and the port name to X (don't be alarmed; after the application has started, you will get the opportunity to choose a proper COM-name!) 然后,在“属性”窗口里,设置串口参数为9600,8 N1和端口名称为X(不要惊慌,在应用程序启动后,你将有机会选择正确的COM名!)
Now, place the top-textbox (txtIn), showing received data, and the lower textbox (txtOut), showing the data to be send after clicking the Send button. Optionally, you could also place a StatusStrip (as I did). 现在,放置页最上方文本框(txtIn),用它表示接收到的数据,和页下方文本框(txtOut),用它表示发出的数据,点击“发送”按钮就会发送。可选的步骤有,您也可以增加 StatusStrip(像我一样)。
Add a ComboBox (cmbComSelect) with DropDownStyle set to and Sorted set to true. 添加一个ComboBox(cmbComSelect),DropDownStyle设置为DropDown, Sorted设置为true。

The Namespace命名空间

The System.IO.Ports namespace contains classes for controlling serial ports. The most important class is the SerialPort class.System.IO.Ports命名空间中包含的类用于控制串行端口。最重要的类是 SerialPort类。

The Code代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace RS232
{
public partial class fclsRS232Tester : Form
{
string InputData = String.Empty;
// This delegate enables asynchronous calls for setting
// the text property on a TextBox control:// 此委托实现异步调用   此调用可设置      一个TextBox控件的text属性         
delegate void SetTextCallback(string text);
public fclsRS232Tester()
{
InitializeComponent();
// Nice methods to browse all available ports:浏览所有可用的端口的最佳方法 
string[] ports = SerialPort.GetPortNames();
// Add all port names to the combo box:/ / 添加所有的端口名称的组合框 
foreach (string port in ports)
{
cmbComSelect.Items.Add(port);
}
}
private void cmbComSelect_SelectionChangeCommitted(object sender, 
EventArgs e)
{
if (port.IsOpen) port.Close();
port.PortName = cmbComSelect.SelectedItem.ToString();
stsStatus.Text = port.PortName + ": 9600,8N1";
// try to open the selected port:/ / 尝试打开选定的端口: 
try 
{
port.Open();
}
// give a message, if the port is not available:/ /如果该端口是不可用的,发出信息: 
catch 
{
MessageBox.Show("Serial port " + port.PortName + 
" cannot be opened!", "RS232 tester", 
MessageBoxButtons.OK, MessageBoxIcon.Warning);
cmbComSelect.SelectedText = "";
stsStatus.Text = "Select serial port!";
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if (port.IsOpen) port.WriteLine(txtOut.Text);
else MessageBox.Show("Serial port is closed!", 
"RS232 tester", 
MessageBoxButtons.OK, 
MessageBoxIcon.Error);
txtOut.Clear();
}
private void btnClear_Click(object sender, EventArgs e)
{
txtIn.Clear();
}
private void port_DataReceived_1(object sender, 
SerialDataReceivedEventArgs e)
{
InputData = port.ReadExisting();
if (InputData != String.Empty)
{
//txtIn.Text = InputData;
// because of different threads this
// does not work properly !!,因为不同的线程
// 不正常工作! 
SetText(InputData);
}
}
/*
To make a thread-safe call a Windows Forms control:

为了实现对Windows窗体控件的线程安全调用:

1. Query the control's InvokeRequired property.查询控件的InvokeRequired属性。

2. If InvokeRequired returns true, call Invoke with a delegate that makes the actual call to the control. 如果InvokeRequired返回真,提供委托来调用Invoke,让委托完成对控件的实际调用。

3. If InvokeRequired returns false, call the control directly.如果InvokeRequired返回假,直接调用该控件。 In the following code example, this logic is implemented in a utility method called SetText. A delegate type named SetTextDelegate encapsulates the SetText method. When the TextBox control's InvokeRequired returns true, the SetText method creates an instance of SetTextDelegate and calls the form's Invoke method. This causes the SetText method to be called on the thread that created the TextBox control, and in this thread context the Text property is set directly

在下面的代码示例中,这个逻辑是由一个工具方法setText来实施。
命名为SetTextDelegate的委托类型封装SetText方法。
当TextBox控件的InvokeRequired 返回true,SetText方法创建一个SetTextDelegate的委托实例和调用窗体的Invoke方法。这将导致SetText方法在创建TextBox控件的线程上调用
,在此线程上下文中Text属性被直接设置

also see: http://msdn2.microsoft.com/en-us/library/ms171728(VS.80).aspx

还可以参考:http://msdn2.microsoft.com/en-us/library/ms171728(VS.80).aspx

*/ 
// This method demonstrates a pattern for making thread-safe
// calls on a Windows Forms control. 此方法说明了对Windows窗体控件线程安全调用中的一个模式 
//
// If the calling thread is different from the thread that
// created the TextBox control, this method creates a
// SetTextCallback and calls itself asynchronously using the
// Invoke method.如果调用线程和创建TextBox控件的线程不是一个线程
/ /此方法创建一个SetTextCallback委托实例且使用Invoke方法异步调用自己
// If the calling thread is the same as the thread that created
// the TextBox control, the Text property is set directly. 
如果调用线程和创建TextBox控件的线程是一个,则
//直接设置Text属性 
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.InvokeRequired需要比较调用线程的线程ID和创建线程ID
/ /
/ / 如果这些线程是不同的,则返回true。 
if (this.txtIn.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else this.txtIn.Text += text;
}
}
}
友情链接
版权所有 Copyright(c)2004-2024 锐英源软件
统一社会信用代码:91410105098562502G 豫ICP备08007559号 最佳分辨率 1440*900
地址:郑州市金水区文化路97号郑州大学北区院内南门附近