web-dev-qa-db-ja.com

Task.Delayを使用する場合、Thread.Sleepを使用する場合

Task.DelayThread.Sleep を使用する場合の適切な規則はありますか。

  • 具体的には、一方を他方よりも効果的/効率的にするために提供する最小値はありますか?
  • 最後に、Task.Delayはasync/awaitステートマシン上でコンテキスト切り替えを引き起こすので、それを使用することによるオーバーヘッドはありますか?
286
Tom K.

現在のスレッドをブロックしたい場合はThread.Sleepを使用してください。

現在のスレッドをブロックせずに論理的な遅延が必要な場合は、Task.Delayを使用してください。

効率はこれらの方法の最優先事項ではありません。それらの実世界での主な用途は、I/O操作の再試行タイマーであり、ミリ秒ではなく秒のオーダーです。

291
Stephen Cleary

現在のスレッドが強制終了され、Thread.Sleepを使用していて実行中の場合は、ThreadAbortExceptionが返される可能性があります。 Task.Delayを使えば、いつでもキャンセルトークンを提供して、それを優雅に殺すことができます。私がTask.Delayを選択する理由の1つはそれだけです。 http://social.technet.Microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx を参照してください。

この場合、効率性が最優先事項ではないことにも同意します。

26
Balanikas

何か追加したいのですが。実際、Task.Delayはタイマーベースの待機メカニズムです。 source を見ると、遅延の原因となっているTimerクラスへの参照が見つかります。一方、Thread.Sleepは実際に現在のスレッドをスリープ状態にします。つまり、1つのスレッドをブロックして無駄にしているだけです。非同期プログラミングモデルでは、少し遅れて何か(継続)が起こるようにしたい場合は、常にTask.Delay()を使うべきです。

20
crypted