第13章. スケジューリング
この作品はAIを使って翻訳されている。ご意見、ご感想をお待ちしている:translation-feedback@oreilly.com
コードが実行されるとき、それはどこかのスレッドで実行されなければならない。スケジューラとは、あるコードがどこで実行されるかを決定するオブジェクトである。.NETフレームワークには数種類のスケジューラがあり、並列コードとデータフロー・コードで若干の違いがある。
通常はデフォルトが正しい。たとえば、非同期コードのawait 演算子は、レシピ 2.7 で説明するように、デフォルトをオーバーライドしない限り、同じコンテキスト内でメソッドを自動的に再開する。同様に、リアクティブ・コードには、イベントを発生させるための合理的なデフォルト・コンテキストがあり、レシピ6.2で説明するように、ObserveOn で上書きすることができる。
他のコードを特定のコンテキスト(UIスレッドコンテキストやASP.NETリクエストコンテキストなど)で実行する必要がある場合は、この章のスケジューリングレシピを使ってコードのスケジューリングを制御できる。
13.1 スレッドプールへの仕事のスケジューリング
問題
スレッドプールのスレッドで明示的に実行したいコードがある。
解決策
大部分の場合、Task.Run を使いたいだろう。これは非常に簡単だ。次のコードは、スレッドプールのスレッドを2秒間ブロックする:
Tasktask=Task.Run(()=>{Thread.Sleep(TimeSpan.FromSeconds(2));});
Task.Run も戻り値や非同期Lambdaをうまく理解する。以下のコードで が返すタスクは、2秒後に13という結果で完了する:Task.Run
Task<int>task=Task.Run(async()=>{awaitTask.Delay(TimeSpan.FromSeconds(2));return13;});
Task.Run は、 (または )を返す。これは、非同期またはリアクティブなコードで自然にコンシューマできる。Task Task<T>
ディスカッション
Task.Run はUIアプリケーションに最適で、UIスレッドで実行できないような時間のかかる作業を行う場合に使用する。例えば、レシピ8.4では、 、並列処理をスレッドプールスレッドにプッシュしている。しかし、自分が何をしているのかTask.Run 絶対に分かっているという確信がない限り、ASP.NET上で 。ASP.NETでは、リクエスト処理コードはすでにスレッドプールスレッドで実行されているので、それをTask.Run 別のスレッドプールスレッドにプッシュすることは通常逆効果である。
Task.Run は、 、 、 の効果的な置き換えである。これらの古いAPIはいずれも新しいコードで使用すべきではない。 を使用するコードは、正しく記述し、長期間にわたって保守するのがはるかに簡単である。さらに、 は、 のユースケースの大部分を処理しているため、 のほとんどのユースケースも、 で置き換えることができる(シングルスレッド・アパートメント・スレッドという稀な例外を除く)。BackgroundWorker Delegate.BeginInvoke ThreadPool.QueueUserWorkItem Task.Run Task.Run Thread Thread Task.Run ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access