Sae*_*ani 2 .net c# serial-port winforms
我正在开发一个串口相关的应用程序.使用I DataReceived事件SerialPort需要使用接收的字节更新文本框:
private void Connection_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var data = Connection.ReadExisting();
_readBuffer.Add(indata);
Invoke(new EventHandler(AddReceivedPacketToTextBox));
}
Run Code Online (Sandbox Code Playgroud)
所以我Invoke用来更新文本框.但是有一个大问题.当我尝试关闭连接时,我的UI被冻结了,我认为这可能是因为Invoke正在做一些事情.
一位朋友说我应该用RequiredInvoke,但我不知道他真的是什么.如何在不搞乱调用和UI线程的情况下关闭连接?
这是我的近距离方法:
private void DisconnectFromSerialPort()
{
if (Connection != null && Connection.IsOpen)
{
Connection.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
UPDATE
正如汉斯所说我改变Invoke了BeginInvoke但现在情况有点糟糕,我的应用程序InvalidOperationException因为收集_readBuffer被修改而停止工作(这就是VS中的细节所说的)
这是我在文本框中添加文本的代码:
private void AddReceivedPacketToTextBox(object sender, EventArgs e)
{
foreach (var i in _readBuffer)
tbIn.Text += string.Format("{0:X2} ", i);
tbIn.Text += Environment.NewLine;
ScrollToBottom(tbIn);
label4.Text = _receivedPackets.ToString();
_receivedPackets++;
_readBuffer.Clear(); //Possibly because clearing collection gets out of sync with BeginInvoke??
}
Run Code Online (Sandbox Code Playgroud)
第二次更新
我仍然有问题,改变了Invoke()以BeginInvoke没;吨帮助.我还尝试添加断开连接以形成关闭事件nu成功...任何时候我关闭我的表单它得到股票(我的意思是它的父表单,因为这个有权访问serialport的表单是从另一个表单`调用.
我的意思是我发现UI只在两种情况下被锁定:如果我计时调用按钮,Connection.Close() 如果我尝试关闭表单,那么父表单将抛出一些对象被处置的异常.
我从父表单中调用这样的串行表单:
public DebugForm DebugForm;
private void button1_Click(object sender, EventArgs e)
{
if (DebugForm != null)
{
DebugForm.BringToFront();
return;
}
DebugForm = new DebugForm();
DebugForm.StartPosition = FormStartPosition.CenterScreen;
DebugForm.Closed += delegate
{
WindowState = FormWindowState.Normal;
DebugForm = null;
};
DebugForm.Show();
WindowState = FormWindowState.Minimized;
}
Run Code Online (Sandbox Code Playgroud)
这可能是问题吗?!
是的,这段代码在Close()调用中导致死锁的几率非常高.在DataReceived事件处理程序停止运行之前,串行端口无法关闭.但是,在UI线程空闲并泵送消息循环之前,Invoke()调用无法完成.它不是空闲的,它停留在Close()调用中.所以事件处理程序无法取得进展,因为它停留在Invoke()调用中,并且你的主线程无法取得进展,因为它停留在Close()调用,死锁城市.
最好的解决方法是使用BeginInvoke(),而不是阻止事件处理程序.根本没有关闭串口是另一种解决方法,这是可以的,因为Windows会在程序终止时自动处理它.通常,在设备忙于发送数据时关闭串行端口是不确定的,并且不可避免地导致数据丢失.好的,当你调试你的代码但不是你通常希望在生产中看到的东西时.
| 归档时间: |
|
| 查看次数: |
4686 次 |
| 最近记录: |