C# 使用 Task.Factory 时捕获错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14883850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Catching Error when using Task.Factory
提问by twaldron
i am using the following
我正在使用以下
Task.Factory.StartNew(() => DoPrintConfigPage(serial));
then the function i am calling looks like this
那么我正在调用的函数看起来像这样
private void DoPrintConfigPage(string serial)
{
//do printing work
}
My problem is an exception is being thrown inside the thread and not being handled.
我的问题是在线程内部抛出了一个异常并且没有被处理。
I have tried wrapping it in a try catch
我试过把它包装在一个 try catch 中
try
{
Task.Factory.StartNew(() => DoPrintConfigPage(serial));
}
catch (Exception ex) { }
but it still is not catching the error and thus crashing the application.
但它仍然没有捕捉到错误,从而导致应用程序崩溃。
How can I catch exceptions in the main thread so I can handle them?
如何在主线程中捕获异常以便处理它们?
Update
更新
I have made the changes recommended below and still it is saying the exception is unhandled
我已经进行了下面推荐的更改,但仍然说异常未处理
var task = Task.Factory.StartNew(() => DoPrintConfigPage(serial))
.ContinueWith(tsk =>
{
MessageBox.Show("something broke");
},TaskContinuationOptions.OnlyOnFaulted);
then in my DoConfigPage
I added another try catch.
然后在我的DoConfigPage
我添加了另一个尝试捕获。
In this catch is now where it is crashing and saying the exception being thrown was unhandled, what am I missing?
在这个捕获现在它崩溃并说抛出的异常未处理,我错过了什么?
private void DoPrintConfigPage(string serial)
{
try
{
//call the print function
}
catch (Exception ex)
{
throw ex; //it is crashing here and saying it is unhandled
}
}
I also tried what Eric J. suggested with the same results
我也尝试了 Eric J. 建议的相同结果
var task = Task.Factory.StartNew(() => DoPrintConfigPage(serial));
try
{
task.Wait();
}
catch (AggregateException ex) { MessageBox.Show("something broke"); }
采纳答案by JerKimball
Alternatively, you can chain your task creation and add a ContinueWith:
或者,您可以链接您的任务创建并添加一个 ContinueWith:
var job = Task.Factory
.StartNew(...)
.ContinueWith(tsk =>
{
// check tsk for exception and handle
});
EDIT: This snippet, when run, pops up the message box for me:
编辑:此代码段在运行时为我弹出消息框:
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!");
}
回答by Eric J.
Your try
block is exited right after you start the new task, because that method just continues to run.
try
在您开始新任务后,您的块会立即退出,因为该方法只是继续运行。
Instead you can catch the Exception as an AggregateExceptionwhere you wait for the task (or multiple tasks) to complete:
相反,您可以将异常作为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;
}
}
}
回答by Timothy Shields
You should also know about System.Threading.Tasks.TaskScheduler.UnobservedTaskException.
您还应该了解 System.Threading.Tasks.TaskScheduler.UnobservedTaskException。
If you are in the business of creating "fire and forget" Task
instances, you'll want to subscribe to that event at the start of your program.
如果您从事创建“即发即弃”Task
实例的业务,您需要在程序开始时订阅该事件。
回答by s????
If you are not waiting on your task, I think the easiest solution is found in Task.Exception:
如果你没有等待你的任务,我认为最简单的解决方案是在Task.Exception 中找到:
Gets the AggregateException that caused the Task to end prematurely. If the Task completed successfully or has not yet thrown any exceptions, this will return null.
获取导致 Task 提前结束的 AggregateException。如果任务成功完成或尚未抛出任何异常,则返回 null。
I am using something like this:
我正在使用这样的东西:
Task.Factory.StartNew(() => DoStuffHere())
.ContinueWith(task =>
{
if (task.Exception != null)
Log("log all the exceptions!");
});
回答by MiGro
Maybe you are trying to catch a Corrupted State Exception. Since .NET 4 applications are unable to catch such exceptions by default. You could try to add the legacyCorruptedState--ExceptionsPolicy=true
entry to your configuration file as stated in the MSDN article linked above.
也许您正在尝试捕获Corrupted State Exception。由于 .NET 4 应用程序默认无法捕获此类异常。您可以尝试将legacyCorruptedState--ExceptionsPolicy=true
条目添加到您的配置文件中,如上面链接的 MSDN 文章中所述。