public static Task WhenAllCancelOnFailure(IEnumerable <Func <CancellationToken, Task> > functions, CancellationToken cancellationToken) { var functionsArray = functions.AsArray(); if (functionsArray.Length == 0) { return(Task.CompletedTask); } if (functionsArray.Length == 1) { return(functionsArray[0](cancellationToken)); } CancellationTokenSource cts; try { cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); } catch (Exception) when(cancellationToken.IsCancellationRequested) { return(Task.FromCanceled(cancellationToken)); } var tcs = new TaskCompletionSourceEx <bool>(); var state = new WhenAllCancelOnFailureContinuationState(functionsArray.Length, tcs, cts); foreach (var function in functionsArray) { Task.Run(() => function(cts.Token) .ContinueWith(WhenAllCancelOnFailureContinuation, state, default(CancellationToken), TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)); } return(tcs.Task); }
public static Task WhenAllCancelOnFailure(IEnumerable <Func <CancellationToken, Task> > functions, CancellationToken cancellationToken) { var functionsList = functions.ToList(); var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); var tcs = new TaskCompletionSourceEx <bool>(); var state = new WhenAllCancelOnFailureContinuationState(functionsList.Count, tcs, cts); Parallel.ForEach(functionsList, function => { var task = function(cts.Token); task.ContinueWith(WhenAllCancelOnFailureContinuation, state, default(CancellationToken), TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); }); return(tcs.Task); }