c# - C#中的跨线程事件处理

标签 c# winforms multithreading event-handling

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

class SomeDataSource {

    public event OnFrameworkEvent;

    void FrameworkCallback() {

        // This function runs on framework's thread.

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

我想将这些事件传递给 Winforms 线程上的 Winforms 对象。我显然检查了 InvokeRequired 并在必要时将其分派(dispatch)给 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;
  1. 现在,这种方法是线程安全的吗?如果窗体正在关闭过程中,并且外部线程调用了 BeginInvoke,调用是否会如果表单关闭,是否仍要排队等待执行? (这意味着我仍然有机会遇到同样的问题)

  2. 是否有更好的跨线程事件处理方法或推荐模式?

最佳答案

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

检查 this thread了解更多信息。

关于c# - C#中的跨线程事件处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2159176/

相关文章:

c# - 回发时列表框重复(重复)

android - Glide assert : java. lang.IllegalArgumentException: 你必须在主线程上调用这个方法

c# - httpClient 告诉我错误 c# winform

c# - c#中数值递增的问题

c# - 适用于 .net 的 Google 提醒 API

c# - 如何通过同步实现 C# Winforms 数据库应用程序?

C# winforms向动态创建的标签页添加控件

c# - 卸载 Windows 应用程序后删除已安装的目录

c# - 绑定(bind)到由在后台工作的线程创建的对象的属性

c# - 使用 C# 和 APM 时 CPU 使用率不会达到 100% 的原因是什么?