私は最近、私は多くの場所で説明を見てきました打ち消しパターンを使用して非同期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
は私にとって正しい選択ではありません。それはがのように私はそれをもっと複雑にするように感じます。状況に照らされたどんな光も、最も高く評価されるだろう。
@AlexeiLevenkovなぜあなたはそれが何をしていると思いますか? – i3arnon
あなたは 'Task.Delay'に渡されたトークンのキャンセルが正しいとタイマーを処理します。私は、通常のタスクがキャンセルのためにチェックするように振る舞うと仮定しましたが、そうでないことが判明しました。 –
@ i3arnon、ありがとう。はい - 私は多くを適用するパターンを探しています。私は以前あなたの答えの一つに空の続きがあるのを見て、この質問を見ることを望んでいました。タイムアウトタスクへのこのアプローチは、_ベストプラクティス_ではなく、_ベストプラクティス_になっているようですが、これが良い、悪い、またはそうでないと思っているのでしょうか? – Clay