7

http://msdn.microsoft.com/en-US/library/vstudio/hh191443.aspxを読んでいました。コード例:

async Task<int> AccessTheWebAsync()
{ 
    // You need to add a reference to System.Net.Http to declare client.
    HttpClient client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the 
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork();

    // The await operator suspends AccessTheWebAsync. 
    //  - AccessTheWebAsync can't continue until getStringTask is complete. 
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    //  - Control resumes here when getStringTask is complete.  
    //  - The await operator then retrieves the string result from getStringTask. 
    string urlContents = await getStringTask;

    // The return statement specifies an integer result. 
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    return urlContents.Length;
}

このページには次のようにも書かれています。

async および await キーワードによって、追加のスレッドが作成されることはありません。非同期メソッドは独自のスレッドで実行されないため、非同期メソッドはマルチスレッドを必要としません。

この「追加のスレッドは作成されません」は、非同期としてマークされたメソッドの範囲内に適用されますか?

GetStringAsync と AccessTheWebAsync の両方を同時に実行するには (そうしないと、AccessTheWebAsync が制御できるようになったため GetStringAsync は終了しません)、最終的に GetStringAsync は AccessTheWebAsync のスレッドとは別のスレッドで実行する必要があると思います。

私にとって、非同期メソッドを書くことは、それが待機しているメソッドも非同期である場合にスレッドを追加しない場合にのみ役立ちます(すでに余分なスレッドを使用して独自のことを並行して実行しています)

私の理解は正しいですか?

4

4 に答える 4

14

これが の力の鍵ですasyncGetStringAsyncおよびその他の自然に非同期の操作には、スレッドは必要ありませんGetStringAsyncHTTP リクエストを送信し、サーバーが応答したときに実行するコールバックを登録するだけです。サーバーが応答するのを待つだけのスレッドは必要ありません。

実際には、スレッド プールはごくわずかしか使用されません。上記の例では、によって登録されたコールバックGetStringAsyncはスレッド プール スレッドで実行されますが、AccessTheWebAsync実行を継続できることを通知するだけです。

役に立つと思われるasync紹介ブログ投稿があります。

于 2013-07-18T22:04:52.613 に答える
2

GetStringAsync と AccessTheWebAsync の両方が同時に実行されるように想像します...

それらは同時には実行されません (少なくとも、あなたが考えている方法では)。ここで、HttpClient.GetStringAsync 自体が

  • 別のスレッドで作業を開始した場合、そのコードが同時に実行されている可能性があります。
  • await (ConfigureAwait(false) を使用) があれば、そのメソッドの残りの作業はスレッド プール スレッドにスケジュールされます (そのため、コードを同時に実行できます)。

ポイントは、メソッドを として宣言しasyncたり、 , を使用したりしてawaitも、作成しているメソッドが別のスレッドで実行されるわけではないということです (明示的に実行する必要があります)。

Note: Without having the code (or documentation) of another asynchronous method, you don't really know how much of it is run synchronously. It doesn't really start being asynchronous until that method does an await or explicitly starts work on another thread (usually by starting a new Task)

于 2013-07-18T22:05:29.740 に答える
-3

ここで著者が言っているのは、単純に async キーワードと await キーワードをどこかで使用しても、現在のメソッドが別のスレッドで実行されるわけではないということです。提供されたコードで何が起こるかを調べてみましょう。

async Task<int> AccessTheWebAsync()
{ 
    // You need to add a reference to System.Net.Http to declare client.
    HttpClient client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the 
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

ここまでのすべてが 1 つのスレッドで実行されました。この時点で、 client.GetStringAsync 呼び出しは新しいスレッドをスピンオフする可能性があります (ただし、これは非同期メソッドで保証されているわけではありません)。ただし、GetStringAsync メソッドは基本的にこの現在のスレッドで開始されますが (実際に呼び出しを行うなど)、応答の読み取りは返された後に別のスレッドで実行されることに注意してください。これは、Task オブジェクトを返すことで表されます。Task は、すでに完了した作業の一部、現在実行中のセカンダリ スレッド、または単に後で実行するようにスケジュールされた作業単位を表す場合があります。

DoIndependentWork();

これは、呼び出しがキューに入れられた (または場合によっては送信された) 後、プライマリ スレッドで実行されるようになりました。したがって、これは、リクエストが返されるのを待っている間に発生する可能性があります。まだプライマリ スレッドにいることに注意してください。

 string urlContents = await getStringTask;

この時点で、スレッドが戻ります。.NET はメソッドの残りを含む継続関数を作成し (return urlContents.Length;)、独自のスレッドで getStringTask が完了すると自動的に呼び出されます。その時点で、新しいスレッドが継続を取得します。

このすべてを通じて、 await キーワードまで、 async メソッドに記述したすべてが 1 つのスレッドで実行されました。確かに、別のスレッドを生成する可能性のある別のメソッドを呼び出しましたが、async/await キーワードを使用するだけで別のスレッドを作成するために行ったことはありません。最後の継続はおそらく別のスレッドによって呼び出される可能性がありますが、最初の関数が実際に戻った後です (これが、この関数への呼び出しが戻ったときにまだ完了していない可能性がある作業を表すために、関数が Task オブジェクトを返す理由です)。 .

于 2013-07-18T22:08:23.033 に答える