给出以下简化代码
/// <summary>
/// Within the VS2010 debugger, the following test will cease with an
/// "Exception was unhandled by user code".
/// (Debug window reports a "A first chance exception of type
/// 'System.Exception' ..." BEFORE the exception is caught
/// further down in the execution path.)
/// OUTSIDE the VS2010 debugger, the exception is caught by the tComplete
/// task that follows the tOpen task, just as expected.
/// </summary>
public void StartToOpen_Simple()
{
Task tOpen = Task.Factory.StartNew(() => {
//do some work before spawning another task here
try
{
return Task.Factory.StartNew(() => {
Thread.Sleep(2000);
//First chance exception occurs here:
throw new Exception("Some generic exception");
}, TaskCreationOptions.AttachedToParent);
} catch (Exception ex)
{
//never fires
var source = new TaskCompletionSource<object>();
source.TrySetException(ex);
return source.Task;
}
}).Unwrap();
Task tComplete = tOpen.ContinueWith(t => {
if (t.Exception != null)
{
Exception LastOpenException = t.Exception.Flatten().GetBaseException();
if (LastOpenException is OperationCanceledException)
{
Console.WriteLine("OperationCanceledEx: " + LastOpenException.Message);
} else
{
Console.WriteLine("Some exception occured in the tOpen task, but we're prepared for it here in the tComplete task.");
Console.WriteLine("The exception message was: {0}", LastOpenException.Message);
}
} else
{
//do something if no exception occured (doesn't happen in this example)
}
}, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.AttachedToParent, TaskScheduler.Default);
}
并通过
测试它 static void Main(string[] args)
{
AsyncTest test = new AsyncTest();
test.StartToOpen_Simple();
Console.WriteLine("Started async task. Waiting for exception");
Console.ReadKey();
}
我在VS2010调试器中运行它时发现了一个非常烦人的问题:就像“摘要”状态一样,调试器在'tOpen'任务中抛出,相信我没有捕获异常(我做了) “tComplete”任务中的“进一步低于”。只有当我继续调试会话时,才会看到异常“冒泡”并因此按需处理。如果这个方法是在一个固定的时间间隔(它是!)上运行的,那么调试就变成了一场噩梦,因为调试器会在每个时间间隔内中断。
在控制台上运行程序,不会出现此行为。