后台工作线程不会从ThreadPool捕获错误
本文关键字:ThreadPool 错误 工作 线程 后台 | 更新日期: 2023-09-27 18:01:36
我使用BackgroundWorker,因为我需要在我的UI中给出反馈。我还需要在我的类中使用ThreadPool来异步运行,但似乎我的后台工作人员无法捕获它抛出的异常。
它的目的是给出一个关于它正在做什么任务的反馈。
我做了一个简单的应用程序,它再现了这个问题:
// MAIN UI CLASS
BackgroundWorker _bgWorker = new BackgroundWorker();
void _bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
// Returns custom error
MessageBox.Show(e.Error.Message);
}
}
void _bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
try {
// Initialize test error class
var testClass = new TestClass();
}
catch (Exception ex)
{
MessageBox.Show("im from trycatch");
}
}
private void Window_ContentRendered(object sender, EventArgs e)
{
_bgWorker.DoWork += _bgWorker_DoWork;
_bgWorker.RunWorkerCompleted += _bgWorker_RunWorkerCompleted;
}
/////////////////////////////////////////////////////////////////////////
// TEST ERROR CLASS
public TestClass()
{
throw new Exception("im a custom error");
}
可以正常工作。使用try-catch,它捕获由try-catch处理的错误。然而,没有try-catch,它在RunWorkerCompleted中处理它。
然而,我真的需要异步地做这些方法(这就是为什么我使用ThreadPool),但是调试器总是指向异常。(只有当我在没有调试器的情况下尝试它时才会崩溃)
// TEST ERROR CLASS
public TestClass()
{
ThreadPool.QueueUserWorkItem(delegate
{
throw new Exception("im a custom error");
}
}
我尝试使用try-catch语句重新抛出错误(希望它将异常传递给BackgroundWorker),但它没有工作。
希望你能帮助我。
您不需要从DoWork方法中将代码放在ThreadPool上。当你调用RunWorkerAsync()
时,BackgroundWorker会自动触发ThreadPool线程上的_bgWorker_DoWork
方法。
如果你试图从后台工作器启动更多的线程池任务,那么我想这可能是一个考虑因素,但在这种情况下,我会建议在。net 4中使用TPL,如果可能的话…
http://msdn.microsoft.com/en-us/library/dd460717 (v = vs.110) . aspx
如果你不能使用TPL,那么你必须把你的ThreadPool代码包装在TryCatch中,并把异常放在可以在该方法之外访问的地方。
例如,在你的UI类中添加一个internal static List<Exception> backgroundExceptions;
成员,后台工作器将任何捕获的异常添加到这个列表中,然后你必须在后台工作完成后调查这个列表,看看是否有任何异常存在。
这就是TPL为你所做的…给你一个地方"观察"发生在后台线程的异常,但它仍然是你的责任去寻找这些异常,无论是在Task.Exception
属性,或通过调用一个方法,将重新抛出异常为你。