I recently asked a question about the possibility of cleaning up some code, the code was meant to wait for each Task in a List<Task<T>> to complete but cancelling all Task if one returned some falsey value.
A user named Servy quickly produced a method which eloquently orders a List<Task<T>> by their completion time. After reading over the answer a bit I think/thought I understand/stood the method. I then went to use the method but quickly realized an issue. I need to be able to recognize the Tasks as they are completing. But the Order method Servy suggested provides no means to do this (because I cannot compare the task continuations returned by Order to my List<Task<>> I supplied it originally). 
So I went to change the method to return a Tuple<T, int> where the int represents the original index of the Task in the provided arguments. 
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);
}
// Usage
foreach(var task in myTaskList.OrderByCompletion())
    Tuple<Boolean, int> result = await task;
The issue I am facing is that index inside of the Tuple returned seems to always be equal to the Count of the original List<Task<>> passed to OrderByCompletion no matter the order of the task returned. 
I assume that as a result of this issue I do not fully understand how this method worked in the first place, though it seems to be that it should work just fine.
Can anyone explain the issue and offer a solution?
 
     
    