I recently asked a question about the possibility of cleaning some code, the code had to wait until everyone Taskin List<Task<T>>, but canceled all Taskif you returned a value of false.
A user named Servy quickly created a method that eloquently orders List<Task<T>>by the time they are completed. After reading the answer a bit, I think / thought I understand / there was a method. Then I went to use the method, but quickly realized the problem. I need to be recognized Taskas they are completed. But the method Orderproposed by Servy does not provide any means for this (because I can not compare the continuation of the task returned Order, in mine List<Task<>>, I put it initially).
So, I went to change the method to return Tuple<T, int>where it intrepresents the source index Taskin the arguments provided.
public static IEnumerable<Task<Tuple<T, int>>> OrderByCompletion<T>(IEnumerable<Task<T>> tasks)
{
var taskList = tasks.ToList();
var taskSources = new BlockingCollection<TaskCompletionSource<Tuple<T, int>>>();
var taskSourceList = new List<TaskCompletionSource<Tuple<T, int>>>(taskList.Count);
for (int i = 0; i < taskList.Count; i++)
{
var task = taskList[i];
var newSource = new TaskCompletionSource<Tuple<T, int>>();
taskSources.Add(newSource);
taskSourceList.Add(newSource);
task.ContinueWith(t =>
{
var source = taskSources.Take();
if (t.IsCanceled)
source.TrySetCanceled();
else if (t.IsFaulted)
source.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCompleted)
source.TrySetResult(new Tuple<T, int>(t.Result, i));
}, CancellationToken.None, TaskContinuationOptions.PreferFairness, TaskScheduler.Default);
}
return taskSourceList.Select(tcs => tcs.Task);
}
foreach(var task in myTaskList.OrderByCompletion())
Tuple<Boolean, int> result = await task;
, , , Tuple Count List<Task<>>, OrderByCompletion .
, , , , .
- ?