C#中的跨线程事件处理 [英] Cross-thread event handling in C#

查看:285
本文介绍了C#中的跨线程事件处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  class SomeDataSource {

public event OnFrameworkEvent;

void FrameworkCallback(){

//此函数运行在框架的线程上。

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;




  1. 现在,这种方法线程安全?如果表单处于关闭状态,外线调用 BeginInvoke ,表单关闭后,调用是否仍然排队等待执行? (这意味着我仍然有机会遇到相同的问题)


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



解决方案

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



有关详细信息,请查看此主题


I am working with a framework that runs its own event dispatcher in a separate thread. The framework may generate some events.

class SomeDataSource {

    public event OnFrameworkEvent;

    void FrameworkCallback() {

        // This function runs on framework's thread.

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

I want to deliver these events to a Winforms object on Winforms thread. I obviously check for InvokeRequired and dispatch it to Winforms thread if necessary.

class SomeForm : Form {

    // ...

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

        // ...
    }

}

Now events may be delivered when the form is in the process of being closed, which causes all sorts of problems, so I unregister the form's event handler from framework's event source on Winforms thread like this:

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

// ...

src.OnFrameworkEvent += form.SomeAction;
form.Closing += (sender, eargs) => src.OnFrameworkEvent -= form.SomeAction;

  1. Now, is this approach thread-safe? If the form is in the process of being closed, and a foreign thread calls BeginInvoke, will the invocation still be queued for execution if the form is closed? (which means I still have a chance of encountering the same problem)

  2. Is there a better approach or recommended pattern for cross-thread event handling?

解决方案

No it is not. The thread might just be executing the event handler while you unregister it and close the form. Small odds, but not zero. You have to have the thread stopped before you can close the form. If you don't want to abort it, you'll have to keep the form open by canceling the FormClosing event, then let the thread's completion callback close the form.

Check this thread for more info.

这篇关于C#中的跨线程事件处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆