In his PluralSight Asynchronous C # 5 course, Jon Skeet provides this implementation for a convenience extension method called InCOmpletionOrder:
public static IEnumerable<Task<T>> InCompletionOrder<T>(this IEnumerable<Task<T>> source) { var inputs = source.ToList(); var boxes = inputs.Select(x => new TaskCompletionSource<T>()).ToList(); int currentIndex = -1; foreach (var task in inputs) { task.ContinueWith(completed => { var nextBox = boxes[Interlocked.Increment(ref currentIndex)]; PropagateResult(completed, nextBox); }, TaskContinuationOptions.ExecuteSynchronously); } return boxes.Select(box => box.Task); } private static void PropagateResult<T>(Task<T> completedTask, TaskCompletionSource<T> completionSource) { switch(completedTask.Status) { case TaskStatus.Canceled: completionSource.TrySetCanceled(); break; case TaskStatus.Faulted: completionSource.TrySetException(completedTask.Exception.InnerExceptions); break; case TaskStatus.RanToCompletion: completionSource.TrySetResult(completedTask.Result); break; default: throw new ArgumentException ("Task was not completed."); } }
In this matter, Martin Neal provides a seemingly more elegant return-return implementation.
public static IEnumerable<Task<T>> InCompletionOrder<T>(this IEnumerable<Task<T>> source) { var tasks = source.ToList(); while (tasks.Any()) { var t = Task.WhenAny(tasks); yield return t.Result; tasks.Remove(t.Result); } }
While still somewhat new to harsh asynchronous programs, can anyone describe the specific problems that may arise during the implementation of Martin Neal, which are properly resolved by John Skeet, more involved in the implementation
source share