2015-09-06 4 views
7

私は最近、私は多くの場所で説明を見てきました打ち消しパターンを使用して非同期WCFサービスメソッドの全体の束を再実装しました。もちろん、既存のタスクは取り消し可能ではありませんが、それは将来のリリースでうまく処理されるはずです。私の場合はTask.Delay Worth Cancellationですか?あなたが開始したタスクとTask.Delayに<code>Task.WhenAny</code>を待つ -

は、Task.Delayのデフォルトの継続時間は、サービスの設定によって支配されています。圧倒的多数のケースでは、結果は、必要な時間内に希望のタスクが完了するという結果になります。設定はしばしば寛大である。

のほとんどは(すべてではない)私が見てきた例はTask.Delayをキャンセルする気にしないでください。それはそれほど安いのではないかと心配する価値はありますか?私はキャンセルが例外を提起することを知っています。遅延をキャンセルすると、例外を処理する必要がありますか?

private async Task<T> GetOrTimeout<T>(Task<T> task, [CallerMemberName] string caller = "") 
{ 
    using (var cts = new CancellationTokenSource()) 
    { 
    try 
    { 
     var timeout = GetDelay(cts.Token); 
     var first = await Task.WhenAny(task, timeout); 
     if (first == timeout) throw new TimeoutException(Properties.Resources.TimeoutOccurredInService.Fmt(caller)); 
     cts.Cancel(); //--> haven't been doing this. Should I? 
     return await task; 
    } 
    catch (Exception ex) 
    { 
     throw LoggedFaultException(ex, caller); 
    } 
    } 
} 

...と遅延は次のようになります作成方法:

private Task GetDelay(CancellationToken token) 
{ 
    return Task 
    .Delay(Properties.Settings.Default.ServiceMethodTimeout, token) 
    .ContinueWith(_ => { }, TaskContinuationOptions.ExecuteSynchronously); 
} 

をした場合ここで

は、私はすべてのサービスメソッドを経由呼び出していることを作った方法です私は遅れを取り消しません、私は必要以上に長く資源を保持していますか?特に、私は、WCFがサービスメソッドを呼び出すためにスピンアップするインスタンスが心配です。私は、サービスが構成されている同時実行性のパラメータを削減することに懸念しています。タイムアウトの設定はかなり粗いです。キャンセルしないのは無駄なようですが、これはまったく新しいものです。

キャンセルには例外が含まれており、状態を伝達するために例外を使用しないように訓練されているので、これは私が完全に理解していないひどい反パターンに気づいたように感じます。おそらくTask.Delayは私にとって正しい選択ではありません。それはのように私はそれをもっと複雑にするように感じます。状況に照らされたどんな光も、最も高く評価されるだろう。

答えて

2

まず、この全体的な問題はパフォーマンス上無視できるものであり、実際の環境でテストした後にのみ他の点で考慮する必要があります。我々は潜る場合

はしかし、Task.Delayは一定の間隔後に完了したタスクを作成します。新しいSystem.Threading.TimerIDisposableを実装する)を作成して、ThreadPoolスレッドを使用して間隔後に約束タスクを完了します。

あなたはTask.Delay「ロット」を使用している場合は、彼らは便利だずっと後にぶらぶら無駄なリソースのかなりの量を持つことができます。 Task.Delayタスクに継続を追加する場合は、参照をキャプチャするデリゲートを追加しても、理由もなくハングアップします。

そうです、それはおそらくあまりないことでも、代わりにそれが出て実行させるのタスクをキャンセルする方が安全です。

+0

@AlexeiLevenkovなぜあなたはそれが何をしていると思いますか? – i3arnon

+0

あなたは 'Task.Delay'に渡されたトークンのキャンセルが正しいとタイマーを処理します。私は、通常のタスクがキャンセルのためにチェックするように振る舞うと仮定しましたが、そうでないことが判明しました。 –

+0

@ i3arnon、ありがとう。はい - 私は多くを適用するパターンを探しています。私は以前あなたの答えの一つに空の続きがあるのを見て、この質問を見ることを望んでいました。タイムアウトタスクへのこのアプローチは、_ベストプラクティス_ではなく、_ベストプラクティス_になっているようですが、これが良い、悪い、またはそうでないと思っているのでしょうか? – Clay

関連する問題