C#Task.WaitAll()取消错误处理
问题描述:
我有一个问题。 我尝试运行多个长时间运行的任务。如果一个失败,我想取消所有其他任务并获得失败例外。 下面给出的例子。与异常 我想捕捉AggregateException通过C#Task.WaitAll()取消错误处理
throw new Exception("FailureTask");
抛出但不是AggregateException我赶上OperationCanceledException,因为我想取消所有其他任务。
[TestMethod]
public void TestParallelTaskCancelation()
{
var cancellationTokenSource = new CancellationTokenSource();
Task[] tasks =
{
Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
Task.Factory.StartNew(FailureTask, cancellationTokenSource, cancellationTokenSource.Token)
};
try
{
Task.WaitAll(tasks, cancellationTokenSource.Token);
}
catch (OperationCanceledException e)
{
Console.WriteLine(e.GetaAllMessages());
}
catch (AggregateException e)
{
Console.WriteLine(e.GetaAllMessages());
}
}
private void DummyTask(object o)
{
var cancellationToken = (CancellationTokenSource)o;
while (true)
{
Thread.Sleep(10000);
if (cancellationToken.IsCancellationRequested)
{
cancellationToken.Token.ThrowIfCancellationRequested();
}
}
}
private void FailureTask(object o)
{
var cancellationToken = (CancellationTokenSource)o;
var executionTask = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
throw new Exception("FailureTask");
}, cancellationToken.Token);
executionTask.ContinueWith(t =>
{
cancellationToken.Cancel(false);
throw new Exception(t.Exception.GetaAllMessages());
}, TaskContinuationOptions.OnlyOnFaulted);
if (executionTask.Wait(10 * 1000, cancellationToken.Token)) return;
//timeout !!!
throw new Exception("The limit 'Max Seconds Per Query' has been exceeded!!!");
}`
请帮忙。
答
这对我的作品
public static async void TestParallelTaskCancelation()
{
var cancellationTokenSource = new CancellationTokenSource();
Task[] tasks =
{
Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
Task.Factory.StartNew(FailureTask, cancellationTokenSource, cancellationTokenSource.Token)
};
try
{
await Task.WhenAll(tasks);
}
catch (OperationCanceledException e)
{
Console.WriteLine(e.ToString());
}
catch (AggregateException e)
{
Console.WriteLine(e.ToString());
}
}
答
您应该投掷AggregateException
构造函数,而不是仅仅Exception
使用:
throw new AggregateException ("FailureTask");
你抛出一个'Exception'这是所有异常的基类。 'OperationCanceledException'和'AggregateException'派生自'Exception'。你的例外永远不会被捕获,因为你只是捕获更具体的例外。要捕获一个'AggregateException',你必须抛出一个'AggregateException'。 –
如果两个或更多任务同时失败,该怎么办?那么我会抓住哪个例外?我所理解的是,AggregateException应该包括已取消任务的取消异常和其他任务的异常。 – Gintaras
抛出新的AggregateException(“FailureTask”);没有工作。即使仅捕获(基本)异常捕获OperationCanceledException。 – Gintaras