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

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

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

o_Typing是从TabPage派生的类中的一种方法。 基本上,我希望每个对话都有自己的选项卡。

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

当事件被触发时, MessageBox弹出,但Tab标题不会改变。 事件触发一次后,它再也不会触发,这让我相信这个事件在工作线程中被调用,尽管它在UI线程中定义。

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


有两种选择:

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

2)在引发事件之前,让工作者线程编组回到UI线程 - 换句话说,使用Control.Invoke作为引发事件的过程的一部分,这样事件处理程序将全部在UI线程中调用。 根据您的应用的结构,您可能不希望事件提升组件明确了解UI,但在构建时您可以传入ISynchronizeInvokeControl实现),并且组件可以使用它来提升其事件在正确的线程上。 当然,如果每个事件处理程序都很乐意在同一个线程上运行,那么它就可以工作(无论如何) - 但通常情况就是这样。 你会写如下的东西:

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);
    }
}

如果您在工作线程执行的代码中激发事件,则订阅该事件的所有方法都将在该工作线程下执行。

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

最好的祝福

链接地址: http://www.djcxy.com/p/68063.html

上一篇: C#, Event Handlers and Threading

下一篇: Order of event handler execution