从原始线程调用事件?

时间:2010-04-08 12:54:45

标签: c# events multithreading

这是我的问题,我有一个类,它有一个抛出一个事件的对象,在这个事件中我从我的类中抛出一个自定义事件。但不幸的是,原始对象从另一个线程抛出事件,所以我的事件也抛出另一个线程。当我的自定义事件尝试从控件访问时,这会导致异常。

以下是一个更好理解的代码示例:

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我得到一个跨线程异常,因为它已在另一个线程上调用。

我想要做的是在原始类线程上抛出自定义事件,因此可以在其中使用控件。

任何人都可以帮助我?

3 个答案:

答案 0 :(得分:4)

您可以查看InvokeRequired / Invoke模式。

在尝试更新某些控件之前,请检查是否需要调用并使用Invoke方法,该方法将处理对已创建此控件的线程的调用:

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

答案 1 :(得分:0)

我不确定是否是这种情况,但如果它是安全的,您可以添加到表单构造函数中:

Control.CheckForIllegalCrossThreadCalls= false;

这是“简单方法”,仅适用于某些有限的情况。就我而言,就像一个魅力。

答案 2 :(得分:0)

您似乎需要查看SynchronizationContextAsyncOperation类。

http://www.codeproject.com/KB/cpp/SyncContextTutorial.aspx