私はC#の新しいasync
およびawait
演算子について読んでいて、どのような状況でそれらが私に役立つ可能性があるかを理解しようとしました。私はいくつかのMSDNの記事を研究しましたが、これが行間で読んだものです。
WindowsフォームとWPFイベントハンドラーにはasync
を使用できるため、操作の大部分が実行されている間、UIスレッドをブロックすることなく長いタスクを実行できます。
_async void button1_Click(object sender, EventArgs e)
{
// even though this call takes a while, the UI thread will not block
// while it is executing, therefore allowing further event handlers to
// be invoked.
await SomeLengthyOperationAsync();
}
_
await
を使用するメソッドはasync
である必要があります。つまり、コード内のどこかでasync
関数を使用すると、最終的には呼び出しシーケンスのすべてのメソッドがUIイベントハンドラーから強制されます。最下位レベルのasync
メソッドもasync
になるまで。
つまり、通常の古き良きThreadStart
エントリポイント(または古き良きstatic int Main(string[] args)
のコンソールアプリケーション)でスレッドを作成する場合、async
とを使用することはできません。 await
ある時点でawait
を使用し、それを使用するメソッドをasync
にする必要があるため、呼び出し元のメソッドでもawait
そしてそれをasync
などにします。ただし、スレッドのエントリポイント(またはMain()
)に到達すると、await
が制御を譲る呼び出し元はありません。
したがって、基本的には、標準のWinFormsとWPFメッセージループを使用するGUIがないと、async
とawait
を使用できません。 MSDNは、async
プログラミングはマルチスレッドを意味するのではなく、代わりにUIスレッドの空き時間を使用すると述べているので、それはすべて理にかなっていると思います。コンソールアプリケーションまたはユーザー定義のエントリポイントを持つスレッドを使用する場合、非同期操作を実行するにはマルチスレッドが必要になります(互換性のあるメッセージループを使用しない場合)。
私の質問は、これらの仮定は正確ですか?
したがって、基本的に、標準のWinFormsとWPFメッセージループを使用するGUIがないと、非同期を使用して待機することはできません。
それは絶対にないの場合です。
WindowsフォームとWPFでは、async
/await
には、待機していた非同期操作が完了したときにUIスレッドに戻るという便利なプロパティがありますが、それが唯一の目的であるとは限りません。それに。
非同期メソッドがスレッドプールスレッドで実行される場合-例: Webサービスでは、継続(非同期メソッドの残りの部分)は、コンテキスト(セキュリティなど)が適切に保持された状態で、anyスレッドプールスレッドで実行されます。これは、スレッドの数を抑えるのに非常に役立ちます。
たとえば、トラフィックの多いWebサービスがあり、そのほとんどが他のWebサービスにリクエストをプロキシしているとします。ネットワークトラフィックによるものであれ、別のサービス(データベースなど)での本物の時間によるものであれ、ほとんどの時間を他のことを待つことに費やしています。そのために多くのスレッドは必要ありませんが、呼び出しをブロックすると、当然、リクエストごとにスレッドが作成されます。 async/awaitを使用すると、スレッドが非常に少なくなります。これは、リクエストがlotであっても、ある時点で実際に実行する必要のあるリクエストが非常に少ないためです。飛行中」。
問題は、async/awaitがUIコードで最も簡単にできることですデモンストレーションバックグラウンドスレッドを適切に使用するか、UIスレッドで多くの作業を行うことの苦痛を誰もが知っているからです。それは、機能が役立つ唯一の場所であるという意味ではありません-それから遠く離れています。
さまざまなサーバーサイドテクノロジ(MVCやWCFなど)はすでに非同期メソッドをサポートしており、他のテクノロジもそれに続くことを期待しています。
Awaitを使用するメソッドは非同期である必要があります。つまり、コード内のどこかで非同期関数を使用すると、UIイベントハンドラーから最下位レベルの非同期メソッドまでの呼び出しシーケンスのすべてのメソッドも非同期になります。
Trueではありません-asyncとマークされたメソッドは、awaitを使用できることを意味しますが、これらのメソッドの呼び出し元には制限がありません。メソッドがTask
または_Task<T>
_を返す場合、それらはContinueWith
または4.0のタスクで実行できる他のすべてを使用できます。
UI以外の良い例は、MVC4AsyncControllerです。
最終的に、async/awaitは主にコンパイラーの書き換えを目的としているため、同期コードのように見えるものを記述し、async/awaitが追加される前に必要だったすべてのコールバックを回避できます。また、SynchronizationContextの処理にも役立ち、スレッドアフィニティ(UIフレームワーク、ASP.NET)のあるシナリオに役立ちますが、それらがなくても引き続き役立ちます。たとえば、Mainは常にDoStuffAsync().Wait();
を実行できます。 :)
私の質問は、これらの仮定は正確ですか?
番号。
WindowsフォームとWPFイベントハンドラーに非同期を使用できるため、操作の大部分が実行されている間、UIスレッドをブロックすることなく長いタスクを実行できます。
本当。 SilverlightやWindowsStoreなどの他のUIアプリケーションにも当てはまります。
また、alsoはASP.NETにも当てはまります。この場合、ブロックされないのはHTTPリクエストスレッドです。
Awaitを使用するメソッドは非同期である必要があります。つまり、コード内のどこかで非同期関数を使用すると、UIイベントハンドラーから最下位レベルの非同期メソッドまでの呼び出しシーケンスのすべてのメソッドも非同期になります。
これはベストプラクティスですが( "async
ずっと下に")、厳密には必須ではありません。非同期操作の結果をcanブロックします。多くの人がコンソールアプリケーションでこれを行うことを選択します。
通常の古き良きThreadStartエントリポイント
えーと…「普通の古き良き」を問題にしなければなりません。私のブログで説明しているように、 Thread
は、バックグラウンド操作を行うための最悪のオプションです 。
私の async
とawait
の紹介を確認し、 async
/await
をフォローアップすることをお勧めしますFAQ 。