这是我的问题,我有一个类,它有一个引发事件的对象,在这种情况下,我从类中引发了一个自定义事件。但是不幸的是,原始对象从另一个线程抛出了事件,所以我的事件也被抛出了另一个线程。当我的自定义事件尝试从控件访问时,这会导致异常。
这是一个代码示例,可以更好地理解:
class MyClass
{
// Original object
private OriginalObject myObject;
// My event
public delegate void StatsUpdatedDelegate(object sender, StatsArgs args);
public event StatsUpdatedDelegate StatsUpdated;
public MyClass()
{
// Original object event
myObject.DoSomeWork();
myObject.AnEvent += new EventHandler(myObject_AnEvent);
}
// This event is called on another thread while myObject is doing his work
private void myObject_AnEvent(object sender, EventArgs e)
{
// Throw my custom event here
StatsArgs args = new StatsArgs(..........);
StatsUpdated(this, args);
}
}
因此,在Windows窗体上,我调用尝试从StatsUpdated事件中更新控件时,我得到一个跨线程异常,因为该异常已在另一个线程上调用。
我想要做的是将自定义事件扔到原始类线程上,以便可以在其中使用控件。
有人可以帮助我吗?
最佳答案
您可以看看InvokeRequired/Invoke模式。
在尝试更新某些控件之前,请检查是否需要invoke并使用Invoke方法,该方法将处理对创建此控件的线程的调用编码(marshal)处理:
Control ctrlToBeModified = //
if (ctrlToBeModified.InvokeRequired)
{
Action<Control> del = (Control c) =>
{
// update the control here
};
ctrlToBeModified.Invoke(del, ctrlToBeModified);
}
更新:
private void myObject_AnEvent(object sender, EventArgs e)
{
// Throw my custom event here
StatsArgs args = new StatsArgs(..........);
Control control = // get reference to some control maybe the form or 'this'
if (control.InvokeRequired)
{
Action<Control> del = (Control c) =>
{
// This will invoke the StatsUpdated event on the main GUI thread
// and allow it to update the controls
StatsUpdated(this, args);
};
control.Invoke(del);
}
}