web-dev-qa-db-ja.com

非同期呼び出しをすぐに待機しています

継承されたプロジェクトで作業しているときに、元の開発者が多くの非同期関数を作成していることに気付きましたであることを利用することは決してありません非同期。例えば:

_// The async method
private async Type myFuncAsync() { .. gets something from DB .. }

//  Example of how the method is consistently utilized
public async Type seaHorses() {
   var seaPony = await myFuncAsync();
   .. do stuff ..
}
_

私の理解では、これは無意味です。なぜなら、awaitメソッドを起動するときに常にasyncをすぐに呼び出す場合、同期コードを作成しているだけだからです。それは書くことと同じです:

_// The sync method
private Type myFunc() { .. gets something from DB .. }

//  Example of how the method is consistently utilized
public Type seaHorses() {
   var seaPony = myFunc();
   .. do stuff ..
}
_

asyncメソッドを効率的に使用すると、次のようになります。

_// The async method
private async Type myFuncAsync() { .. gets something from DB .. }

//  Example of how the method is consistently utilized
public async Type seaHorses() {
   var loveSeaHorses = myFuncAsync();
   .. do stuff ..
   await loveSeaHorses;
}
_

この仮定は正しいですか?常にasyncがすぐに呼び出されるawaitとして定義されたメソッドを使用することに反対する理由はありますか?

注:いくつかの調査から、awaitをすぐに呼び出すとメインスレッドが実行を継続することを意味するという漠然とした理解があります。上記の例では、seaHorses()内のmyFuncAsync()が完了するまで、seaHorses()の後のすべての処理がメインスレッドで行われることを意味します。これにより、次のシナリオを指摘して質問することができますこれが非同期プログラミングの実際の不適切な使用である場合

_// The async method
private async Type myFuncAsync() { .. gets something from DB .. }

//  Example of how the method is consistently utilized
public async Type seaHorses() {
   var seaPony = await myFuncAsync();
   .. do stuff ..
}

// Main Thread
Program {
   .. do stuff ..
   var waterHorses = await seaHorses();
   .. do stuff..
}
_
6
8protons

await の呼び出しを誤解していると思います。 asyncとawaitが行うことは、(メインスレッドだけでなく)実行中のスレッドが作業を継続できるようにすることです。これをサポートするメカニズムは 継続 と呼ばれます。そのため、IOのスレッドブロッキング(待機)の代わりに、他のタスクを実行できます。 awaitのタスクが完了すると、スレッドはそのポイントから続行されます。

この値は直感的には思えないかもしれませんが、スレッド管理のオーバーヘッドが利点を上回る前に、現代のマシンは非常に多くのOSスレッドしかサポートできません。この種の「軽量スレッド」により、システムレベルのスレッドをより効率的に使用できます。たとえば、Webサーバーは、それほど遠くない昔の典型的な数百のスレッドを使用する代わりに、少数のスレッドを使用して多数の同時リクエストをサポートできます。

11
JimmyJames