从另一个线程捕获异常
Posted
技术标签:
【中文标题】从另一个线程捕获异常【英文标题】:catching exceptions from another thread 【发布时间】:2010-09-16 09:09:51 【问题描述】:我有一个在单独的线程中运行的方法。线程是从 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);
【问题讨论】:
【参考方案1】:因此,从外观上看,您正在使用 Invoke 编组回 UI 线程 - 这正是您需要做的。为简单起见,我个人会使用 Action
【讨论】:
谢谢,我以前从未使用过 Action请改用 .NET 框架中的 BackgroundWorker 类。这是在不同线程上执行 UI 工作的最佳做法。
【讨论】:
【参考方案3】:可能更好的方法是将委托传递给线程,而不是对表单本身的引用。
【讨论】:
【参考方案4】:在线程之间抛出异常并不容易,也可能是不希望的。相反,您可以使用共享数据结构或变量传递异常,并使用 waitHandle 在第一个线程上等待。
【讨论】:
【参考方案5】:我完全同意 Dror。在正式的方式中,我们可以将此结构称为 FaultContract。从根本上说,当另一个线程中发生异常时,客户端线程此时几乎不能做任何事情,除了收集该信息并在自己的阅读中采取相应的行动。如果 thereads 在不同的 AppPool 中,那么序列化会更加复杂(这可以完全是一个单独的主题)。
【讨论】:
以上是关于从另一个线程捕获异常的主要内容,如果未能解决你的问题,请参考以下文章