我正在使用以下
Task.Factory.StartNew(() => DoPrintConfigPage(serial));
然后我调用的函数看起来像这样
private void DoPrintConfigPage(string serial)
{
//do printing work
}
我的问题是在线程内部抛出异常并且没有被处理。
我尝试将其包装在try catch
中try
{
Task.Factory.StartNew(() => DoPrintConfigPage(serial));
}
catch (Exception ex) { }
但它仍然没有捕获错误,从而导致应用程序崩溃。
如何在主线程中捕获异常,以便我可以处理它们?
我已经进行了下面推荐的更改,但仍然表示异常未处理
var task = Task.Factory.StartNew(() => DoPrintConfigPage(serial))
.ContinueWith(tsk =>
{
MessageBox.Show("something broke");
},TaskContinuationOptions.OnlyOnFaulted);
然后在我的DoConfigPage
我添加了另一个尝试捕获。
在这个问题中,它现在崩溃并且说抛出的异常未处理,我错过了什么?
private void DoPrintConfigPage(string serial)
{
try
{
//call the print function
}
catch (Exception ex)
{
throw ex; //it is crashing here and saying it is unhandled
}
}
我也尝试了Eric J.建议的相同结果
var task = Task.Factory.StartNew(() => DoPrintConfigPage(serial));
try
{
task.Wait();
}
catch (AggregateException ex) { MessageBox.Show("something broke"); }
答案 0 :(得分:35)
或者,您可以链接创建任务并添加ContinueWith:
var job = Task.Factory
.StartNew(...)
.ContinueWith(tsk =>
{
// check tsk for exception and handle
});
编辑:此代码段在运行时会弹出消息框:
void Main()
{
var serial = "some serial";
var task = Task.Factory
.StartNew(() => DoPrintConfigPage(serial))
.ContinueWith(tsk =>
{
MessageBox.Show("something broke");
var flattened = tsk.Exception.Flatten();
// NOTE: Don't actually handle exceptions this way, m'kay?
flattened.Handle(ex => { MessageBox.Show("Error:" + ex.Message); return true;});
},TaskContinuationOptions.OnlyOnFaulted);
}
public void DoPrintConfigPage(string serial)
{
throw new Exception("BOOM!");
}
答案 1 :(得分:9)
启动新任务后立即退出try
块,因为该方法只会继续运行。
相反,您可以将异常作为AggregateException捕获,等待任务(或多个任务)完成:
var task1 = Task.Factory.StartNew(() =>
{
throw new MyCustomException("I'm bad, but not too bad!");
});
try
{
task1.Wait();
}
catch (AggregateException ae)
{
// Assume we know what's going on with this particular exception.
// Rethrow anything else. AggregateException.Handle provides
// another way to express this. See later example.
foreach (var e in ae.InnerExceptions)
{
if (e is MyCustomException)
{
Console.WriteLine(e.Message);
}
else
{
throw;
}
}
}
答案 2 :(得分:7)
如果您没有等待任务,我认为最简单的解决方案可以在http://sqlfiddle.com/#!9/89765/1找到:
获取导致Task过早结束的AggregateException。 如果任务成功完成或尚未抛出任何任务 例外,这将返回null。
我正在使用这样的东西:
Task.Factory.StartNew(() => DoStuffHere())
.ContinueWith(task =>
{
if (task.Exception != null)
Log("log all the exceptions!");
});
答案 3 :(得分:3)
你也应该知道 System.Threading.Tasks.TaskScheduler.UnobservedTaskException
如果您正在创建“即发即弃”Task
个实例,那么您需要在程序开始时订阅该事件。
答案 4 :(得分:0)
也许你正试图抓住Corrupted State Exception。由于.NET 4应用程序默认无法捕获此类异常。您可以尝试将legacyCorruptedStateExceptionsPolicy=true
条目添加到配置文件中,如上面链接的MSDN文章中所述。