使用MVP在线程上运行的串行端口



我有一个名为SerialClient的类,它通过串行端口发送/接收字节。当调用SerialClient.Start()时,它进入无限while循环,直到调用SerialClient.Stop()。这个类有一些属性,为了简单起见,比如SerialClient.PropASerialClient.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#中处理多线程应用程序时,您遇到了两个常见问题:

  1. 正在处理后台线程中的异常。当后台线程中发生异常时,它们会在堆栈中向上移动,从一个调用方移动到另一个调用程序,以查看是否有人能够捕捉到该异常。如果原始呼叫发生在您自己的呼叫之外(例如,来自串行端口或计时器的回调),您可能会也可能不会收到异常通知。作为一个典型的解决方案,我看到的是在try-catch中封装可以引发异常的代码,并让事件处理程序将异常推送到能够适当处理异常的线程(记录、通知用户、终止,所有这些)

  2. 事件总是在调用它们的线程上执行。您必须使用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);
    }
}

相关内容

最新更新