【问题标题】:Cross-thread event handling in C#C#中的跨线程事件处理
【发布时间】:2010-01-29 00:45:10
【问题描述】:

我正在使用一个框架,该框架在单独的线程中运行自己的事件调度程序。框架可能会产生一些事件。

class SomeDataSource {

    public event OnFrameworkEvent;

    void FrameworkCallback() {

        // This function runs on framework's thread.

        if (OnFrameworkEvent != null)
            OnFrameworkEvent(args);
    }
}

我想将这些事件传递给 Winforms 线程上的 Winforms 对象。我显然会检查 InvokeRequired 并在必要时将其分派到 Winforms 线程。

class SomeForm : Form {

    // ...

    public void SomeAction(SomeArgs args) {
        if (InvokeRequired) {
            BeginInvoke(new Action(SomeAction), args);
            return;
        }

        // ...
    }

}

现在可能会在关闭表单的过程中传递事件,这会导致各种问题,所以我在 Winforms 线程上从框架的事件源中取消注册表单的事件处理程序,如下所示:

var form = new SomeForm();
var src = new SomeDataSource();

// ...

src.OnFrameworkEvent += form.SomeAction;
form.Closing += (sender, eargs) => src.OnFrameworkEvent -= form.SomeAction;
    1234563如果表格已关闭? (这意味着我仍有机会遇到同样的问题)
  1. 是否有更好的方法或推荐的跨线程事件处理模式?

【问题讨论】:

    标签: c# winforms multithreading event-handling


    【解决方案1】:

    不,不是。当您取消注册并关闭表单时,该线程可能正在执行事件处理程序。几率很小,但不是零。您必须先停止线程,然后才能关闭表单。如果您不想中止它,则必须通过取消 FormClosing 事件来保持表单打开,然后让线程的完成回调关闭表单。

    查看this thread了解更多信息。

    【讨论】:

    • 我喜欢这种方法。我喜欢在线程完成时使用回调方法发出信号。
    【解决方案2】:

    您可以将此代码添加到构造函数CheckForIllegalCrossThreadCalls = false;,不会抛出异常。

    【讨论】:

      【解决方案3】:

      我没有使用带有自己的事件调度程序的框架,但我对自己创建的线程有自己的经验。这是我的经验

      1. 这种方法不是线程安全的。即使程序本身已关闭,仍会调用该调用。我在任务管理器中看到了这个(在你说程序关闭之后)作为挂起线程。 (即使您也从任务管理器中杀死该程序。)。后来我不得不单独杀死这些线程。

      2. 当表单关闭时,您必须终止调度程序线程,以便在该线程中发生任何错误时它不会挂起。

        form.Closing += (sender, eargs) => src.OnFrameworkEvent -= form.SomeAction;
         // pseudo-code (find c# equivalent)
        if (dispatcherthread.isrunning)
        dispatcherThread.kill();
        

      【讨论】:

      • 如果调度程序线程需要保持活动状态来处理其他 Winform 怎么办?
      • 恐怕是这样。我有多个表单监听同一个事件源。
      • 如果我正确理解你的意思,那么将线程的 IsBackground 属性设置为 true 将防止线程挂起。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多