2017-01-05 10 views
1

私はコンテナが良い/悪い結果のために、各メソッド散布は

Task<Try<SearchResponse>> PerformSearch(SearchRequest request); 

Tryクラスをサポートするサービスの配列から最初の正常な応答に興味を持って状況を持って待って非同期で集まります

(エラーモナドのような)サービスのリストへの呼び出しは、現在FirstOrBadは、拡張メソッドであるこの

var searchResponses = await Task.WhenAll(
     _searchServices.Select(s => s.PerformSearch(request))); 
return searchResponses.FirstOrBad(sr=>sr.IsGood); 

であります最初の良好な結果を見つけたり、すべてのエラーを連結した複合Bad Tryを返します。

は、私の知る限り理解しこれに伴う問題が原因WhenAll最初の良い結果を見つけるために時間を最も遅い応答によって制限されることです。

最初の肯定的な結果を受け取るとすぐに実行を続けますが、最初の(2番目などの)結果は成功しない場合は実行しますが、すべての結果が失敗した場合は実行を継続し、成功。

私はこれが一般的な問題だと思っていましたが、例を探すときはほとんど見つかりませんでした。スキャッターギャザーよりも、他の言葉で知られているかもしれません。

+0

。 https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.whenany(v=vs.110).aspx – Jodrell

+0

@Jodrell - 「Task.WhenAny」がサービスコールが完了しましたか? OPは最初の良い結果が見つかったときに_onlyコールを停止する必要があります – Developer

+0

'Task'の' Cancellation Token'には何か運がありますか?並行してタスクを実行し、良い結果が得られたら他のタスクをキャンセルします。 _少しの思考だけが試したことがありません_ – Developer

答えて

2

このような何かがこの回答から、あなたが

public static async Task<Try<T>> FirstOrBad<T>(this IEnumerable<Task<Try<T>>> tasks, Func<Try<T>, bool> predicate) 
{ 
     var taskList = tasks.ToList(); 
     var completed = new List<Task<Try<T>>>(); 
     Task<Try<T>> completedTask; 
     do 
     { 
      completedTask = await Task.WhenAny(taskList); 
      completed.Add(completedTask); 
      taskList.Remove(completedTask); 
     } while (!predicate(await completedTask) && taskList.Any()); 

     return !predicate(await completedTask) ? new Try<T>(completed.ToString(",")) : await completedTask; 
} 

アダプタのために働く必要がありTPL wait for task to complete with a specific return value

私はあなたが `Task.WhenAny`を使用するか、またはアグリゲータとしてあなた` FirstOrBad`のimplmentationを使用することだろうと思っていると思います