2012年11月8日 星期四

將sub-thread(子執行緒)的Method(方法)丟到main-thread(主執行緒)執行

執行MainForm中的_a.Start()會產生一個子執行緒
當執行緒發生例外時會去觸發ErrorEvent事件
若再catch中直接呼叫 this.ErrorEvent(this, new EventArgs()); 則會發生(InvalidOperationException)例外
(呼叫執行緒無法存取此物件,因為此物件屬於另一個執行緒)
因為Label1在主執行緒中被建立,所以不能被子執行緒直接呼叫。

因此我們可以透過Dispatcher物件來處理這個問題

class MainForm : Form
{
    private _a = new A();

    void Main()
    {
        _a.ErrorEvent += new EventHandler(Alert);
        A.Start();
    }
 
    privaet void Alert(object sender, EventArgs e)
    {
        Label1.Text = "發生例外了!!";
    }

}

class A
{
    private Thread _thread = null;

    private Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
    
    public event EventHandler ErrorEvent;



    public void Start()
    {
        if (_thread == null)
        {
            _thread = new Thread(new ThreadStart(ThreadMethod));
            _thread.Start();
        }
    }

    private void ThreadMethod()
    {
        try
        {
            // do something;
        }
        catch (Exception ex)
        {
            //if (this.ErrorEvent != null) this.ErrorEvent(this, new EventArgs()); <= 錯誤
            if (this.ErrorEvent != null) dispatcher.BeginInvoke(this.ErrorEvent, this, new EventArgs());  <= 正確
        }


    }
}