38

私は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)使用できなくなります。ある時点でを使用する必要があるため、それを使用するメソッドを作成します。したがって、呼び出しメソッドでは、それを使用して作成する必要があります。ただし、スレッドのエントリポイント(または)に到達すると、が制御を譲る呼び出し元はありません。asyncawaitawaitasyncawaitasyncMain()await

したがって、基本的には、標準のWinFormsとWPFメッセージループを使用するGUIがないasyncと使用できません。MSDNは、プログラミングはマルチスレッドを意味するのではなく、代わりにUIスレッドの空き時間を使用するawaitと述べているので、それは確かに理にかなっていると思います。asyncコンソールアプリケーションまたはユーザー定義のエントリポイントを持つスレッドを使用する場合、非同期操作を実行するにはマルチスレッドが必要になります(互換性のあるメッセージループを使用しない場合)。

私の質問は、これらの仮定は正確ですか?

4

4 に答える 4

29

したがって、基本的に、標準のWinFormsとWPFメッセージループを使用するGUIがないと、非同期を使用して待機することはできません。

それは絶対に当てはまりません

WindowsフォームとWPFでは、async/awaitには、待機していた非同期操作が完了したときにUIスレッドに戻るという便利なプロパティがありますが、それが唯一の目的ではありません。

非同期メソッドがスレッドプールスレッドで実行される場合(たとえば、Webサービスで)、継続(残りの非同期メソッド)は、コンテキスト(セキュリティなど)が適切に保持された状態で、任意のスレッドプールスレッドで実行されます。これは、スレッドの数を抑えるのに非常に役立ちます。

たとえば、トラフィックの多いWebサービスがあり、そのほとんどが他のWebサービスにリクエストをプロキシしているとします。ネットワークトラフィックによるものであれ、別のサービス(datbaseなど)での本物の時間によるものであれ、ほとんどの時間を他のものを待つことに費やしています。そのために多くのスレッドは必要ありませんが、呼び出しをブロックすると、当然、リクエストごとにスレッドが作成されます。async / awaitを使用すると、スレッドが非常に少なくなります。これは、「実行中」のリクエストが多数あったとしても、ある時点で実際に実行する必要のあるリクエストが非常に少ないためです。

問題は、async / awaitがUIコードで最も簡単に示されることです。これは、バックグラウンドスレッドを適切に使用するか、UIスレッドで多くの作業を行うことの苦痛を誰もが知っているためです。それは、機能が役立つ唯一の場所であるという意味ではありませんが、それからはほど遠いです。

さまざまなサーバー側テクノロジ(MVCやWCFなど)はすでに非同期メソッドをサポートしており、他のテクノロジもそれに続くことを期待しています。

于 2012-09-29T17:47:51.673 に答える
8

awaitを使用するメソッドは非同期である必要があります。つまり、コード内のどこかで非同期関数を使用すると、UIイベントハンドラーから最下位レベルの非同期メソッドまでの呼び出しシーケンスのすべてのメソッドも非同期になります。

真実ではありません-非同期とマークされたメソッドは、awaitを使用できることを意味しますが、これらのメソッドの呼び出し元には制限がありません。メソッドが戻った場合、TaskまたはメソッドTask<T>が使用できる場合ContinueWith、または4.0のタスクで実行できるその他のこと

UI以外の良い例は、MVC4AsyncControllerです。

最終的に、async / awaitは主にコンパイラーの書き換えを目的としているため、同期コードのように見えるものを記述し、async/awaitが追加される前に行っていたようなすべてのコールバックを回避できます。また、SynchronizationContextの処理にも役立ち、スレッドアフィニティ(UIフレームワーク、ASP.NET)を使用するシナリオに役立ちますが、それらがなくても引き続き役立ちます。たとえば、メインはいつでも実行できDoStuffAsync().Wait();ます。:)

于 2012-09-29T18:01:39.953 に答える
6

私の質問は、これらの仮定は正確ですか?

いいえ。

WindowsフォームとWPFイベントハンドラーに非同期を使用できるため、操作の大部分が実行されている間、UIスレッドをブロックすることなく長いタスクを実行できます。

本当です。SilverlightやWindowsStoreなどの他のUIアプリケーションにも当てはまります。

また、ASP.NETに当てはまります。この場合、ブロックされないのはHTTPリクエストスレッドです。

awaitを使用するメソッドは非同期である必要があります。つまり、コード内のどこかで非同期関数を使用すると、UIイベントハンドラーから最下位レベルの非同期メソッドまでの呼び出しシーケンスのすべてのメソッドも非同期になります。

これはベストプラクティス(「asyncずっと下」)ですが、厳密には必須ではありません。非同期操作の結果をブロックできます。多くの人がコンソールアプリケーションでこれを行うことを選択します。

通常の古き良きThreadStartエントリポイント

えーと…「普通の古き良き」に問題があります。私のブログで説明しているように、これThreadはバックグラウンド操作を行うための最悪のオプションです

との紹介を確認し、 asyncawaitasync/ awaitFAQをフォローアップすることをお勧めします。

于 2012-09-29T19:02:14.960 に答える
0
  1. async-awaitは、タスククラス操作のラッパーにすぎません。これは、その名前が付けられたTasks Parallel Library-TPL(async-await自動コード生成技術の前に公開されたもの)の一部です。
  2. したがって、実際には、async内でUIコントロールへの参照を使用することはできません-await。
  3. 通常、async-awaitは、Webとサーバーの関係、リソースのロード、SQLのための強力なツールです。生きているUIを備えたスマート待機データで動作します。
  4. 通常、TPLアプリケーション:単純な大きなサイズのループから、共有データに基づく複雑な計算での多段階の並列計算まで(ContinueWithなど)
于 2015-11-02T20:08:29.837 に答える