【问题标题】:Handle an event raised from background thread处理从后台线程引发的事件
【发布时间】:2011-03-02 22:00:31
【问题描述】:

我开发了一个类(在 C# 中)用于通过网络发送和接收消息。它创建一个新线程(侦听器线程),等待新消息到达然后引发事件。 问题是在侦听器线程中引发了事件,当我想在 wpf 应用程序中使用此类时,尝试处理事件时发生运行时错误 错误是:调用线程无法访问此对象,因为不同的线程拥有它。

当事件在提到的类中引发时,是否有任何适当的方法来处理这种情况?

【问题讨论】:

    标签: events c#-4.0 multithreading


    【解决方案1】:

    您必须在 UI 线程上才能更新 UI 对象。您可以使用窗口的 Dispatcher 在那里执行代码:

    this.Dispatcher.Invoke(new Action(() =>
    {
        // Code that updates UI here
    }));
    

    【讨论】:

    • 谢谢我知道这个,无论如何我可以从类本身在主线程中引发事件,我的意思是我希望类的用户(wpf)能够处理像其他事件一样的事件
    • 一个事件包含三件事:它在哪个线程上引发,发送者对象和事件参数。您可以提供您想要的任何发送者和事件参数,如果您希望它在 UI 线程上引发,您可以在调度程序方法中触发事件。
    【解决方案2】:

    BackgroundWorker 明确支持编组到 UI 线程。但是,您必须使用它,调用它的 ReportProgress() 方法。虽然针对报告进度进行了优化,但您不必为此使用它。有一个接受对象的重载,你可以传递任何你想要的东西。事件处理程序将其作为 e.UserState 值获取。从那里,您可以直接使用该对象或使用它来重新引发另一组事件。

    请注意该对象的线程安全要求。工作人员继续运行,并且以任何方式与 ProgressChanged 事件处理程序的执行同步。所以它不应该再更新对象。最好在调用 ReportProgress() 后创建它的新实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-28
      • 2011-04-07
      • 1970-01-01
      相关资源
      最近更新 更多