日期:2014-05-17  浏览次数:21103 次

串口 线程,等待 死掉了,如何解决 谢谢
C# code
//开启串口接收线程
serialsReceiveThread = new Thread(new ThreadStart(serialThreadReceive));
serialsReceiveThread.Start();//开始接收线程

sl.writeCommands(cl.cmdsStopAuto(), 0, cl.cmdsStopAuto().Length);
//发送强制停止主动工作模式命令                            
serialAutoEvent.WaitOne();



 接收数据放在线程里处理,
 若设备正确返回,或返回错误引导码带的数据包,则根据命令码,无论,对或错
 都可以serialAutoEvent.Set()动作 
 这样,界面就不会死掉

现在遇到情况是,若设备不返回数据(无论对或错),serialAutoEvent.WaitOne();就一直死等
界面就挂掉了

 设备连上后,PC端串口正确打开了,所以可以自由发送命令码, 但是无意碰断连接,PC是可以继续发送命令的,但是设备已经无法接收到命令,,而PC端一直死等数据
 
 如何完成这个状态下的容错呢?

 谢谢
 

------解决方案--------------------
线程内部做个timer,设置时间,如果此时间内无数据返回,就重置event
------解决方案--------------------
委托异步调用,invoke的方式,waitone设置超时时间,线程内部记得处理异常。
------解决方案--------------------
多线程编程的大忌是随便写出用异步编程语法写出同步阻塞的程序,千万不要滥用WaitOne等阻塞功能语句。千万不要滥用。

接收数据被解析完毕,可以回调预先注册的随后的处理方法。而父线程早就干别的去了(或者结束了),不应该阻塞在那里等着所谓的数据。
------解决方案--------------------
在子线程中操作SerialPort对象实例(不论是调用Read方法还是监听DataReceived事件),都不需要加锁。

我上面所说,主要是针对serialAutoEvent.WaitOne()而言的,也就是父线程不应该“阻塞、等待”。至于处理随后的数据时(例如你需要往一个List<T>里边插入数据,而这个列表有很多线程共享)时是否需要加锁,那是另外一个问题。就从楼主的代码中,看不到需要加锁的需求。

从楼主的问题中,也看不到“超时机制”的任何需求。当线程停止处理SerialPort了,它就停止了,跟父线程毫无关系。而就算是使用DataReceived事件处理,一旦SerialPort对象实例销毁了,那么它也就不触发事件了,也不用设计什么“超时机制”。单从业务描述中,我看不出有什么考虑“超时机制”的必要性。

要描述一个设计的必要性,请举出测试用例。如果没有必要,我们就不要过度设计程序。应当以简单的设计为根本。