考虑下面的代码:如何在使用ContinueWith()时获取原始异常?
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
static class Program
{
static void Main()
{
var tasks = new Task[1];
tasks[0] = Task.Run(() => throwExceptionAfterOneSecond())
.ContinueWith(task => {
Console.WriteLine("ContinueWith()"); }, TaskContinuationOptions.NotOnFaulted);
try
{
Task.WaitAll(tasks);
}
catch (AggregateException ex)
{
Console.WriteLine("Exception received: " + ex.InnerExceptions.Single().Message);
}
}
static void throwExceptionAfterOneSecond()
{
Thread.Sleep(1000);
throw new InvalidOperationException("TEST");
}
}
}
我们得到以下的输出:
Exception received: A task was canceled.
我的问题很简单:我如何获得在原来的InvalidOperationException("TEST");
而非System.Threading.Tasks.TaskCanceledException
?
请注意,如果您删除.ContinueWith()
部件,则按我的预期工作,此时的输出为Exception received: TEST
。
(另请注意,这个例子是使用.NET 4.5,但原代码必须使用.NET 4.0)
SOLUTION
感谢的答案,这是现在的工作。我选择了以下解决方案 - 我需要等待双方的原始任务和后续任务:
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
static class Program
{
static void Main()
{
var tasks = new Task[2];
tasks[0] = Task.Run(() => throwExceptionAfterOneSecond());
tasks[1] = tasks[0].ContinueWith(task => {
if (task.Status == TaskStatus.RanToCompletion)
Console.WriteLine("ContinueWith()"); });
try
{
Task.WaitAll(tasks);
}
catch (AggregateException ex)
{
Console.WriteLine("Exception received: " + ex.InnerExceptions.Single().Message);
}
Console.WriteLine("Done.");
}
static void throwExceptionAfterOneSecond()
{
Thread.Sleep(1000);
throw new InvalidOperationException("TEST");
}
}
}
如何删除'TaskContinuationOptions.NotOnFaulted'? –
@KirillShlenskiy如果你这样做,你从Task.WaitAll()中不会得到任何异常。 –
您正在等待继续任务,而不是内部任务。稍后再添加:'tasks [0] .ContinueWith(...)'。 –