从另一个线程捕获异常

本文关键字:捕获异常 线程 另一个 | 更新日期: 2023-09-27 17:48:52

我有一个方法在一个单独的线程中运行。线程是从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,但基本上你做的是正确的。

在中使用BackgroundWorker类。NET框架。这是在不同线程上执行UI工作的最佳实践。

可能更好的方法是将委托传递到线程中,而不是引用表单本身。

在线程之间引发异常并不容易,而且可能不是所希望的。相反,您可以使用共享数据结构或变量传递异常,并使用waitHandle在第一个线程上等待。

我完全同意Dror的观点。在形式上,我们可以将此结构称为FaultContract。从根本上说,当异常发生在另一个线程中时,客户端线程在那一刻几乎不能做任何事情,除了收集信息并在自己的线程中相应地采取行动。如果它们在不同的AppPool中,那么序列化就有额外的复杂性(这可能是一个单独的主题)。