Пример #1
0
        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);
        }
Пример #2
0
        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);
        }