C# 如何取消并引发任务上的异常。何时引发任何异常?

C# 如何取消并引发任务上的异常。何时引发任何异常?,c#,async-await,task-parallel-library,task,C#,Async Await,Task Parallel Library,Task,我正在使用task.WhenAll等待多个任务。当其中一个生成异常时,我希望Task.whalll(或任何其他等待多个任务的方式)立即取消其他任务并引发异常 CancellationTokenSource cts = new CancellationTokenSource(); var task1 = Func1Async(cts.Token); task1.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOpt

我正在使用task.WhenAll等待多个任务。当其中一个生成异常时,我希望Task.whalll(或任何其他等待多个任务的方式)立即取消其他任务并引发异常

CancellationTokenSource cts = new CancellationTokenSource();

var task1 = Func1Async(cts.Token);
task1.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
var task2 = Func2Async(cts.Token);
task2.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
var task3 = Func3Async(cts.Token);
task3.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);

await Task.WhenAll(task1, task2, task3);
可能吗

提前感谢当所有
无法取消线程时,
可以向所有线程传递
取消令牌
并在出现异常时触发令牌

CancellationTokenSource cts = new CancellationTokenSource();

var task1 = Func1Async(cts.Token);
task1.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
var task2 = Func2Async(cts.Token);
task2.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
var task3 = Func3Async(cts.Token);
task3.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);

await Task.WhenAll(task1, task2, task3);
从方法内部,您需要将
token.ThrowIfCancellationRequested()
放入函数中,以检查令牌并取消任务

public async Task Func1Async(CancellationToken token)
{
    foreach(var item in GetItems1())
    {
         await item.ProcessAsync(token);
         token.ThrowIfCancellationRequested();
    }
}

注意:您可以通过创建一个扩展方法来稍微清理代码

public static class ExtensionMethods
{
    public static Task CancelOnFaulted(this Task task, CancellationTokenSource cts)
    {
        task.ContinueWith(task => cts.Cancel(), cts.Token, taskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
        return task;
    }

    public static Task<T> CancelOnFaulted<T>(this Task<T> task, CancellationTokenSource cts)
    {
        task.ContinueWith(task => cts.Cancel(), cts.Token, taskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
        return task;
    }
}

你能核对一下这个答案吗?这不是Wheall的工作方式。你可能需要重新考虑一下你的方法。@EvertonSantos谢谢你的链接!但我的情况不同,我需要注意例外情况。如果任务中出现异常,我需要取消所有任务OP询问的
whalll
not
WaitAll
@DavidPine第一句中的输入错误,如果你看一下它在那里使用的代码示例。我假设,不想在不知道这是否是故意的情况下编辑您的答案。有用!您忘记将示例中的扩展方法设置为静态。