Invoke机制?界面卡死原因

leafmao 2013-11-25 06:02:38
在SerialPort的DataReceived事件里通过Invoke对UI进行操作,由于串口一直有数据,该事件基本上是一直被触发的。

界面上有一个按钮,执行的是串口的关闭,sp1.Close()。问题在于关闭串口的时候界面会卡死,试过好些次,只要注释掉this.Invoke(new EventHandler(displayInfo));就不会出现卡死情况,问题在于这。

解决办法已经找到了,添加一个判断标志,等待DataReceived事件里的Invoke操作执行完再关闭串口,这样可以避免界面卡死的情况。

想请问为什么会造成界面卡死的情况?关闭了sp1,会让程序卡在this.Invoke(new EventHandler(displayInfo))这吗?Invoke是怎么执行的呢?

private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
...
this.Invoke(new EventHandler(displayInfo));
...
}
...全文
1693 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
leafmao 2013-12-19
  • 打赏
  • 举报
回复
虽然没有满意答案,还是结贴给分吧,我猜测是辅助线程和主线程对UI抢占造成界面卡死。辅助线程里对UI进行操作,而主线程里对SerialPort执行Close操作,造成界面卡死。解决办法我已经在上面贴出来了。
小猪八Q 2013-12-15
  • 打赏
  • 举报
回复
引用 12 楼 h804759109 的回复:
谢谢这个帖子解决了我的问题,我试了下Invoke和BeginInvoke都能正常运行,到底用哪个好点呢? 我给你留言了!
BeginInvoke是异步调用,如果你在调用之后不需要什么其他的反馈,同时又想继续执行下面的代码,可以使用异步调用
荒凉1 2013-12-15
  • 打赏
  • 举报
回复
谢谢这个帖子解决了我的问题,我试了下Invoke和BeginInvoke都能正常运行,到底用哪个好点呢? 我给你留言了!
leafmao 2013-11-26
  • 打赏
  • 举报
回复
关闭sp1的时候会造成界面卡死,我想知道原因是什么,是对UI的抢占造成死锁? 执行sp1.Close()也会对UI进行抢占吗?程序卡死之后,全部中断发现卡在“sp1.Close()” 解决卡死的问题就是加个 while(listening) Application.DoEvents();

bool closePort=false,listening=false;
private void btnOpen_Click(object sender, EventArgs e)
{

                if (btnOpen.Text == "开始监测")
                {
                    sp1.Open();
                    closePort = false;
                    sp1.Write(inquireCommand, 0, 4);
                    btnOpen.Text = "停止监测";
                }
                else if (btnOpen.Text == "停止监测")
                {
                    closePort = true;
                    while (listening)
                        Application.DoEvents();
                    sp1.Close();

                    btnOpen.Text = "开始监测";
                }
}

 private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
 listening=true;
 ...
 this.Invoke(new EventHandler(displayInfo));
 listening=false;
}

private void displayInfo(object sender, EventArgs e)
{
  textBox.text=speed.ToString();
}}
leafmao 2013-11-26
  • 打赏
  • 举报
回复
引用 2 楼 caozhy 的回复:
displayInfo里面怎么写的。
曹版主,帮忙解答下,前两天在另外个帖子看到你对Invoke的解释,但没看到更多的了 Invoke是怎么执行的,执行完毕后是不是通过消息传递什么的 displayInfo里的东西很简单,就是像textBox1.Text=Speed.ToString()这种,而Speed是Int型的类成员
leafmao 2013-11-26
  • 打赏
  • 举报
回复
引用 8 楼 blogtjf 的回复:
不要用ivoke,invoke还是在同一线程,用begininvoke
Invoke是委托到主线程上的。。。不然就会出现跨线程错误了,只是Invoke是同步委托,BeginInvoke是异步委托
宇峰科技 2013-11-26
  • 打赏
  • 举报
回复
不要用ivoke,invoke还是在同一线程,用begininvoke
leafmao 2013-11-26
  • 打赏
  • 举报
回复
引用 6 楼 shencb 的回复:
当SerialPort关闭的时候,displayInfo里面报错了。但很不幸又被你catch了, 所以错误没显示,只是一直假死。
问题不在这。。displayInfo里是没有错误的,而且如果被catch的话,我在catch那加了MessageBox,并无消息框显示。
dacan66 2013-11-25
  • 打赏
  • 举报
回复
当SerialPort关闭的时候,displayInfo里面报错了。但很不幸又被你catch了, 所以错误没显示,只是一直假死。
leafmao 2013-11-25
  • 打赏
  • 举报
回复
引用 2 楼 caozhy 的回复:
displayInfo里面怎么写的。
不知道Invoke委托的方法执行完毕后是不是要通知调用Invoke的线程(即引发sp1_DataReceived事件的线程),而sp1又被关闭了,导致通知对象无响应,于是界面卡死。这也只是我的猜想
leafmao 2013-11-25
  • 打赏
  • 举报
回复
引用 1 楼 yuekunge 的回复:
http://www.cnblogs.com/sufei/p/3145333.html
谢谢你的回复,我已经解决了卡死的问题,但是不明白为什么关闭了sp1,会造成界面卡死
leafmao 2013-11-25
  • 打赏
  • 举报
回复
引用 2 楼 caozhy 的回复:
displayInfo里面怎么写的。
displayInfo里只是简单的对界面上的TextBox进行更新,显示串口接收到的数据
threenewbee 2013-11-25
  • 打赏
  • 举报
回复
displayInfo里面怎么写的。
敌敌畏耶 2013-11-25
  • 打赏
  • 举报
回复
http://www.cnblogs.com/sufei/p/3145333.html

111,093

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧