如何使事件回调到我的win表单线程安全?

问题描述:

当您从表单中订阅对象的事件时,您实际上将对回调方法的控制权交给事件源。你不知道这个事件源是否会选择在不同的线程上触发事件。

When you subscribe to an event on an object from within a form, you are essentially handing over control of your callback method to the event source. You have no idea whether that event source will choose to trigger the event on a different thread.

问题是当回调被调用时,你不能假设你可以在窗体上进行更新控件,因为如果事件回调在不同于运行该表单的线程的线程上被调用,那么这些控件将会抛出一个expires。

The problem is that when the callback is invoked, you cannot assume that you can make update controls on your form because sometimes those controls will throw an expection if the event callback was called on a thread different than the thread the form was run on.

为了简化Simon的代码,您可以使用内置的通用Action代理。它使用一些您不需要的代理类型来保存您的代码。此外,在.NET 3.5中,他们向Invoke方法添加了一个params参数,因此您不必定义一个临时数组。

To simplify Simon's code a bit, you could use the built in generic Action delegate. It saves peppering your code with a bunch of delegate types you don't really need. Also, in .NET 3.5 they added a params parameter to the Invoke method so you don't have to define a temporary array.

void SomethingHappened(object sender, EventArgs ea)
{
   if (InvokeRequired)
   {
      Invoke(new Action<object, EventArgs>(SomethingHappened), sender, ea);
      return;
   }

   textBox1.Text = "Something happened";
}