0

次の質問に基づく: 汎用の FromEvent メソッド

イベントがアプリケーション内のどのスレッドを返すかを知るにはどうすればよいですか? どういうわけか、どのスレッドを続行するかを指定できますか? この機能を使用しているスレッドはどうなりますか?

これらの応答は、WPF (Dispatcher/Main/UI Thread) を使用すると明らかなように見えますが、スレッド MTA、STA、Reactive、ThreadPool (Task/BackgroundWorker) を使用している場合、何が起こるかをどのように予測できますか?

task.Wait() を使用するよりも実際の利点はありますか (スレッドのロックについて心配する必要がない場合)?

4

3 に答える 3

2

の場合await、メソッドTaskを再開するためにキャプチャされて使用される「コンテキスト」がありasyncます。この「コンテキスト」は現在のSynchronizationContextものです。nullTaskScheduler

asyncプログラミングをしている場合は、 awaitand notを使用する必要がありWaitます。Waitブログで説明しているように、デッドロックが発生する可能性があります。

asyncmy / awaitintroも参考になるかもしれません。

于 2013-01-23T18:43:53.363 に答える
2

イベントがアプリケーション内のどのスレッドを返すかを知るにはどうすればよいですか?

あなたはそうしない。特定のイベントのドキュメントで、UI スレッド、スレッド プール スレッドなどから実行されることが指定されていない限り、イベントを使用することはありません。

どういうわけか、どのスレッドを続行するかを指定できますか?

UI スレッドでコードを実行する場合は、イベント ハンドラーで UI スレッドにマーシャリングします。スレッド プール スレッドでコードを実行する場合は、ハンドラー内のスレッド プールに新しいタスクを追加します。これらのタスクはどちらも、不要な場合はオーバーヘッドが追加されるため、通常はイベントのドキュメントを参照して、どちらが必要かを確認することをお勧めします。

ただし、リンクされた質問の場合、全体的な考え方は、イベントとイベント ハンドラーを扱うのではなく、. を扱うということですTask。タスクに継続を追加する場合、問題はその継続がどこで実行されるかです。それはあなたによって完全に指定されています。デフォルトのタスク スケジューラを使用してスレッド プールで実行するか、UI SynchronizationContext を渡して UI スレッドで実行するか、続行しているタスクが実行される場所であればどこでも実行させることができます。(つまり、どのスレッドがそれを実行するかわからないということです。)

でタスクを使用している場合await、その非同期操作を開始する前にあった同期コンテキストで実行するように継続が自動的に構成されます。これは、UI スレッドである場合とそうでない場合があります (ただし、そうである可能性があります)。特にそれを望まない場合は、 を使用して.ConfigureAwait(false);ください。

task.Wait() を使用するよりも実際の利点はありますか (スレッドのロックについて心配する必要がない場合)?

非同期タスク ベースのアプローチを使用する理由は、スレッド、特にスレッド プール スレッドをブロックしていないためです (UI をブロックしていないと明確に述べているため、これはさらに悪いことです)。スレッドが何もせずに放置されていることは問題であり、一部の環境では他の環境よりも問題になります (非常にアクティブなサイトの ASP など)。ブロッキング待機を行わないことで、それらのリソースを消費しません。

于 2013-01-23T18:46:12.340 に答える
1

リンクした手法を使用すると、これが実行されるスレッドを予測できません。イベントを発生させたのはスレッドかもしれませんが、それは保証されていません (いや、そうではありません。これはよくある誤解です)。

したがって、実行したいスレッドに強制的に切り替える必要があります。たとえばTask.Run、スレッド プールに切り替えたりTaskScheduler.FromCurrentSynchronizationContext、UI で実行したりするために使用します。

タスクを実行した場合await、 の前に設定された同期コンテキストで再開することが保証されますawaitこれはおそらくあなたが望むものです。

于 2013-01-23T18:44:20.057 に答える