私のチームには、async Task
を使用したコーディングが大好きな人がいます。また、CancellationToken
パラメータを使用したい場合もあります。
私が確信していないのは、チームとしてこのスタイルのコードを使用する必要があるかどうかです(A):
async Task<someObject> DoStuff(CancellationToken t)
{
while (!t.IsCanceled)
{
try {
Task.Delay(5000, t);
}
catch (AggregateException e) // or is it TaskCanceledException or OperationCanceledException? I don't know? :)
{
}
// poll something, return someObject, or null
}
return null;
}
これは明らかに、呼び出し元が処理を続行するかどうかを決定するためにキャンセルトークン自体をチェックする必要があり、nullretValsを処理する必要がある可能性があることを意味します。
var retVal = await DoStuff(token);
if (token.IsCanceled) { ... }
ただし、TaskCanceledExceptionに依存する2番目のスタイルのコード(B)を採用する場合:
async Task<someObject> DoStuff(CancellationToken t)
{
while(true)
{
Task.Delay(5000, t);
// poll something, return someObject, or null
}
}
実装コードは間違いなく単純です-そして、呼び出し元は必要に応じて例外を処理するかどうかのオプションがあります...しかし、呼び出し元がそうするかもしれないことを心配せずにはいられません忘れる TaskCanceledExceptionは彼らがしなければならないものです心配してください。プロセスがこれらの例外をキャッチしない結果としてクラッシュする可能性があります(フォアグラウンドまたはバックグラウンドスレッドで)。
だから、私の過度に楽観的に表現された質問は次のとおりです:最高スタイルはみんなすべき常に、そしてなぜですか? :)
.Net Framework自体で、 CancellationToken
をパラメーターとして渡すと、 TaskCanceledException
が返されます。 .Netに精通している人はあなたのコードに精通しているので、私はそれに反対せず、独自のデザインパターンを作成します。
私のガイドラインは次のとおりです。トークンをキャンセルするのはTaskCanceledException
を処理する必要があるため、独自の理由でメソッド内でCancellationToken
を使用している場合は、先に進んで使用してください。 try-catch
ブロック。 ただし、トークンをパラメーターとして取得する場合は、例外をスローします。