簡體   English   中英

從另一個線程中捕獲異常

[英]catching exceptions from another thread

我有一個單獨的線程運行的方法。 該線程是從Windows應用程序中的表單創建和啟動的。 如果從線程內部拋出異常,將其傳遞回主應用程序的最佳方法是什么。 現在,我將對主窗體的引用傳遞給線程,然后從線程調用該方法,並使該方法被主應用程序線程調用。 是否有最好的練習方法,因為我現在對自己的表現不滿意。

我的表格示例:

public class frmMyForm : System.Windows.Forms.Form
{
    /// <summary>
    /// Create a thread
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnTest_Click(object sender, EventArgs e)
    {
        try
        {
            //Create and start the thread
           ThreadExample pThreadExample = new ThreadExample(this);
           pThreadExample.Start();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName);
        }
    }

    /// <summary>
    /// Called from inside the thread 
    /// </summary>
    /// <param name="ex"></param>
    public void HandleError(Exception ex)
    {
        //Invoke a method in the GUI's main thread
        this.Invoke(new ThreadExample.delThreadSafeTriggerScript(HandleError), new Object[] { ex });
    }

    private void __HandleError(Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

我的線程類的示例:

public class ThreadExample
{
    public delegate void delThreadSafeHandleException(System.Exception ex);

    private Thread thExample_m;

    frmMyForm pForm_m;
    private frmMyForm Form
    {
        get
        {
            return pForm_m;
        }
    }

    public ThreadExample(frmMyForm pForm)
    {
        pForm_m = pForm;

        thExample_m = new Thread(new ThreadStart(Main));
        thExample_m.Name = "Example Thread";
    }

    public void Start()
    {
        thExample_m.Start();
    }

    private void Main()
    {
        try
        {
            throw new Exception("Test");
        }
        catch (Exception ex)
        {
            Form.HandleException(ex);
        }
    }
}

因此,您正在使用Invoke通過它的外觀來回歸到UI線程 - 這正是您需要做的。 我個人使用Action <Exception>是為了簡單起見,可能是BeginInvoke而不是Invoke,但基本上你做的是正確的。

請改用.NET框架中的BackgroundWorker類。 這是在不同線程上執行UI工作的最佳實踐。

可能更好的方法是將委托傳遞給線程而不是對表單本身的引用。

在線程之間拋出異常並不容易,可能並不需要。 相反,您可以使用共享數據結構或變量傳遞異常,並使用waitHandle在第一個線程上等待。

我完全同意Dror。 以正式的方式,我們可以將此結構稱為FaultContract。 從根本上說,當另一個線程發生異常時,客戶端線程在那個時刻幾乎不能做任何事情,除了收集信息並相應地在它自己的行為中行動。 如果那里有不同的AppPool,那么序列化會有一個額外的復雜性(完全可以是一個單獨的主題)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM