Vim*_*mes 3 c# asynchronous exception-handling .net-4.0 task-parallel-library
我在这里遵循示例代码来了解异步任务.我修改了代码来编写任务工作与主要工作的一些输出.输出将如下所示:

我注意到,如果我删除Wait()调用,程序运行相同,除了我无法捕获任务被取消时抛出的异常.有人可以解释在需要Wait()的幕后发生了什么才能击中catch块吗?
一个警告,Visual Studio调试器将错误地停止Console.WriteLine(" - task work");在行上,并显示消息"OperationCanceledException未被用户代码处理".当发生这种情况时,只需单击继续或按F5查看程序的其余部分.有关详细信息,请参见http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/9946736.aspx.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
class Program
{
static void Main()
{
var tokenSource = new CancellationTokenSource();
var cancellationToken = tokenSource.Token;
// Delegate representing work that the task will do.
var workDelegate
= (Action)
(
() =>
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
// "If task has been cancelled, throw exception to return"
// Simulate task work
Console.WriteLine(" - task work"); //Visual Studio
//erroneously stops on exception here. Just continue (F5).
//See http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/9946736.aspx
Thread.Sleep(100);
}
}
);
try
{
// Start the task
var task = Task.Factory.StartNew(workDelegate, cancellationToken);
// Simulate main work
for (var i = 0; i < 5; i++)
{
Console.WriteLine("main work");
Thread.Sleep(200);
}
// Cancel the task
tokenSource.Cancel();
// Why is this Wait() necessary to catch the exception?
// If I reomve it, the catch (below) is never hit,
//but the program runs as before.
task.Wait();
}
catch (AggregateException e)
{
Console.WriteLine(e.Message);
foreach (var innerException in e.InnerExceptions)
Console.WriteLine(innerException.Message);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
Run Code Online (Sandbox Code Playgroud)
抛出异常时ThrowIfCancellationRequested,它会从您的Task委托中传播出来.此时,它被框架捕获并添加到异常列表中Task.与此同时,这Task又转变为Faulted国家.
理想情况下,您希望观察所有Task异常.如果您使用TaskS作为基于任务的异步模式的一部分,那么在某些时候,你应该await的Task,其传播的第一个例外Task.如果您使用TaskS作为任务并行库的一部分,那么在某些时候,你应该打电话Wait或者Task<T>.Result,它传播的所有的异常Task,包裹在一个AggregateException.
如果您没有观察到Task异常,那么当Task最终确定时,运行时将引发TaskScheduler.UnobservedTaskException然后忽略该异常.(这是.NET 4.5的行为; 4.5之前的行为会引发UnobservedTaskException然后终止进程).
在您的情况下,您不必等待任务完成,因此退出try/catch块.一段时间后,会UnobservedTaskException被引发,然后忽略异常.
| 归档时间: |
|
| 查看次数: |
3263 次 |
| 最近记录: |