C#中的线程事件处理

我正在使用一个在独立线程中运行自己的事件分派器的框架。 该框架可能会产生一些事件。

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;
  • 现在,这种方法是线程安全的吗? 如果表单处于关闭过程中,并且外部线程调用BeginInvoke ,则如果表单关闭,调用是否仍然排队等待执行? (这意味着我仍然有机会遇到同样的问题)

  • 针对跨线程事件处理有更好的方法或推荐模式吗?


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

    检查此线程获取更多信息。


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


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

  • 这种方法不是线程安全的。 即使程序本身已关闭,调用仍将被调用。 我在任务管理器(在程序关闭后,如你所说)看到了这个线程挂起。 (即使你也从任务管理器中终止程序)。 我不得不稍后杀死那些线程。

  • 当表单关闭时,必须杀死调度程序线程,以便在该线程中发生任何错误时不会挂起。

    form.Closing += (sender, eargs) => src.OnFrameworkEvent -= form.SomeAction;
     // pseudo-code (find c# equivalent)
    if (dispatcherthread.isrunning)
    dispatcherThread.kill();
    
  • 链接地址: http://www.djcxy.com/p/68065.html

    上一篇: thread event handling in C#

    下一篇: C#, Event Handlers and Threading