6

非同期/待機コンテキストのキャンセル トークンの代わりに、進行中の非同期操作をキャンセルするメカニズムについて質問があります。これは、言語の命令型の性質を考慮した十分に研究された設計上の決定であると確信していますが、実際の状況では、すべての非同期メソッドにキャンセル オブジェクトを渡さなければならないのは、少なくとも少し苦痛です。C# コミュニティからの別の設計アイデアがありますか、それとも提案されたキャンセル メカニズムで問題ありませんか? 私は何かが欠けていると思います。

4

2 に答える 2

4

キャンセル トークンは、特に非同期プロセスのコストが高い場合、事前に設定された終了条件がない場合、または外部リソースが関係する場合に、ベスト プラクティスとなります。

ただし、必要に応じて、単に「あきらめる」こともできます。非同期スレッドに処理を中止してクリーンアップするように指示する代わりに、単に「タイムアウト」します。完了するのを待つのをやめ、リスナーを切り離して、実行を続けます。スレッドが最終的に完了すると、そのイベントをチェックし、誰もリッスンしていないことを認識し、静かに終了します。利点はシンプルさですが、これが悪いことになる状況がたくさんあります:

  • 停止するように指示しない限り、非同期プロセスが永久に処理を続ける場合、アプリが閉じられるまでバックグラウンドで実行され続け、CPU やその他のリソースが拘束され、スレッドが強制終了されます。
  • 非同期スレッドが、DB 操作などの中止可能で可逆的な作業単位を実行している場合、ユーザーがキャンセルを押すと、それまでに行われたことはすべてロールバックされると想定されます。聞くのをやめて先に進むと、キャンセルしたと思っていたものが実行されたことになります。
  • ほとんどの場合、非同期操作には、作業に時間がかかる外部リソースが含まれ、適切なクリーンアップも必要です。ネットワーク ソケットの切断、DB 接続の切断、ファイルのロック解除などを行う必要があります。あきらめるということは、それに対処する必要がないことを意味しますが、スレッドを正常に終了させる代わりに、ユーザーがうんざりしてヒットするのが一般的なユーザー エクスペリエンスです。キャンセルしてから、操作を再試行してください。つまり、以前の非同期操作で使用したリソースを解放して、再度使用する必要があります。
于 2011-02-07T21:30:22.730 に答える
1

非同期操作のキャンセルを意味のあるものにするためには、その操作で慎重な手順を実行する必要があります。これは、キャンセル トークンをチェックし、それ自体の続行を停止する操作が必要になるためです。つまり、キャンセル トークンは、async/await のメカニズムではなく、実装される単なるパターンです。

つまり、非同期操作が完了ハンドルを使用した 1 つの I/O 呼び出しにすぎない場合、その呼び出しが戻ってくるまで操作にはトークンを確認する機会がないため、キャンセルするのではなくあきらめることもできます。その時点で得られるものは何もありません。

そのため、キャンセル トークンを検討するときは、まず、キャンセルをサポートすることでこの操作をより効率的にできるかどうか、または単に完了を待たない (つまり、代わりにタイムアウト メカニズムを使用する) 方が理にかなっているのかどうかを検討してください。

于 2011-05-28T17:30:10.417 に答える