使用MVP在线程上运行的串行端口
本文关键字:运行 串行端口 线程 MVP 使用 | 更新日期: 2023-09-27 18:24:48
我有一个名为SerialClient
的类,它通过串行端口发送/接收字节。当调用SerialClient.Start()
时,它进入无限while循环,直到调用SerialClient.Stop()
。这个类有一些属性,为了简单起见,比如SerialClient.PropA
、SerialClient.PropB
。
我需要在GUI中使用它。在GUI上,您可以调用"开始"、"停止"并在属性更改时读取属性。
为了在GUI中使用它,显然SerialClient
需要在线程中操作,因为它是一个无休止的循环。因此,我已经设置了属性与SerialClient
相匹配的视图。视图调用演示者上的Start()
和Stop()
。
在演示程序中,我创建了一个新线程,并在SerialClient
对象上调用start。问题是,当_serialClient抛出异常时,演示者无法捕捉到它,而且如果(SerialClient.PropB
)等属性发生更改并调用其更改的事件处理程序,则需要在GUI线程上调用它们。我尝试使用后台工作程序,但无法使其正常工作(更改属性仍然会影响非UI线程的UI)。
Thread thread = new Thread(_serialClient.Start);
thread.IsBackground = true;
thread.Start();
一定有一个简单的解决方案,我正在仔细研究。GUI只需要调用方法和读取属性,并防止异常导致整个应用程序崩溃。
有什么想法吗?
在C#中处理多线程应用程序时,您遇到了两个常见问题:
-
正在处理后台线程中的异常。当后台线程中发生异常时,它们会在堆栈中向上移动,从一个调用方移动到另一个调用程序,以查看是否有人能够捕捉到该异常。如果原始呼叫发生在您自己的呼叫之外(例如,来自串行端口或计时器的回调),您可能会也可能不会收到异常通知。作为一个典型的解决方案,我看到的是在try-catch中封装可以引发异常的代码,并让事件处理程序将异常推送到能够适当处理异常的线程(记录、通知用户、终止,所有这些)
-
事件总是在调用它们的线程上执行。您必须使用Dispatcher和Invoke手动编组对UI线程的调用。我发现最简洁的代码是这里的
void someEvent_Handler(object sender, SomeEventEventArgs e)
{
if (this.Dispatcher.CheckAccess())
{
// do work on UI thread
}
else
{
// or BeginInvoke()
this.Dispatcher.Invoke(new Action(someEvent_Handler),
sender, e);
}
}