C#,事件处理程序和线程

ano*_*ard 8 c# events multithreading worker-thread

我正在写一个小聊天应用程序,我有这个事件处理程序:

void o_Typing(object sender, EventArgs e)
{
    MessageBox.Show("Fired!");
    this.Text = "Fired!";
}
Run Code Online (Sandbox Code Playgroud)

o_Typing是派生自的类中的方法TabPage.基本上,我希望每个对话都有自己的标签.

事件处理程序由我的Chat对象触发,该对象在另一个线程中运行.我有一个用于UI的线程,另一个用于每个聊天对话的线程(用于轮询服务器以获取新数据)

当事件被触发时,会MessageBox弹出,但Tab标题不会更改.事件触发一次之后,它再也不会触发,导致我相信事件是在工作线程中调用的,尽管它是在UI线程中定义的.

如何从工作线程调用我的事件,并使用Invoke()它们在UI线程上执行?

Jon*_*eet 11

有两种选择:

1)使事件处理程序是线程安全的:Control.Invoke/BeginInvoke在任何需要与UI线程通信的事件处理程序中使用.

2)在引发事件之前使工作线程编组回到UI线程 - 换句话说,使用Control.Invoke作为引发事件的过程的一部分,以便在UI线程中调用事件处理程序.根据您的应用程序是如何组织的,你可能不希望您的活动筹集部分了解的UI明确-但它正在建造时,你可以在通过ISynchronizeInvoke(其中Control实现)和你的组件可以用它来提高其对事件正确的线程.当然,如果每个事件处理程序都乐于在同一个线程上运行,那只能(简单地说,无论如何),但通常情况就是这样.你会写一些类似的东西:

protected void OnFoo(EventArgs args)
{
    if (sync != null && sync.InvokeRequired)
    {
        sync.Invoke((Action) delegate { OnFoo(args) }, null);
        return;
    }
    EventHandler handler = Foo; // Where Foo is the event name
    if (handler != null)
    {
        handler (this, args);
    }
}
Run Code Online (Sandbox Code Playgroud)


Oli*_*ppi 6

如果在由工作线程执行的代码中触发事件,那么订阅该事件的所有方法都将在该工作线程下执行.

对于GUI元素,您需要查看Invoke方法.

最好的祝福