私は最近asked a questionいくつかのコードをクリーンアップする可能性について、の各Task
が完了するのを待っていましたが、すべて偽の値を返した場合はすべてTask
を取り消すことを意味していました。引数リストのインデックスを追跡しながら完了時間別にタスクを注文しますか?
Servy quickly produced a methodという名前のユーザーが、納得のいく返答をしてList<Task<T>>
を注文します。答えを少し読んだ後、私は思っています/私は理解していると思った/方法を立っていた。私はその後、この方法を使用するようになりましたが、すぐに問題を認識しました。彼らが完了したときに私はTask
を認識できる必要があります。しかし、Order
メソッドの提案では、これを行う手段がありません。Order
によって返されたタスクの継続と、私がList<Task<>>
を元々供給したものと比較することはできません。
Tuple<T, int>
を返すようにメソッドを変更しました。int
は、指定された引数のTask
の元のインデックスを表します。
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;
私が直面しています問題は、返さTuple
の内部インデックスは常にOrderByCompletion
へのタスクの順序が返さ関係なく渡された元List<Task<>>
のCount
に等しくなるように思われることです。
私は、この問題の結果、最初にこの方法がどのように機能したかを完全に理解していないと思いますが、うまくいくはずです。
誰でも問題を説明して解決策を提示できますか?
オハイオ州ええ!私はブログの記事の前にこの "問題"を見てきました(私はEric Lippertによって考えていますか?)。これは全く意味をなさない。ありがとうございました! – KDecker