2017-01-03 18 views
15

async - awaitを完全に理解しようとしていますが、私の理解の隙間の1つは「すべての道のり」です。 asyncメソッドを作成し、別のasyncメソッドなどから、「UI」や「複数のリクエストを処理できるWebサーバー」のような曖昧な用語で理解できるものをすべて呼び出します。私はどのように技術的に「何と言ってもダウンしている」と表現していますか?「Async All Way Down」:まあ、最下位には何がありますか?

ウェブサーバーの2番目の例を考えてみましょう。私は、.NETソースコードで見つけることができます

[HttpGet] 
public async Task<IHttpActionResult> GetRecords() 
{ 
    var records = await repository.GetRecordsFromDbAsync(); 
    return Ok(records); 
} 

非同期的に呼ばれるように、これを有効に「ダウンすべての方法」のコードのようなコントローラのアクションを持っていると言いますか?

+2

非同期の例を以下に示します。http://stackoverflow.com/q/9963301/87698 – Heinzi

答えて

3

すべての手続き型プログラミング言語は、一連の関数/手続き呼び出しであり、1つの関数/手続きが別の関数/手続きを呼び出します。コールグラフsee Wikipedida for a starting point for call graphsを使用して、プロシージャからプロシージャまでのこの一連のコールを表すことができます。これらのグラフは、一般的に、手続きコールのシーケンスを上から順に示しています。

私は、すぐにASP .NET MVCアプリケーションの部分コールグラフの図を作成しました。図は、オペレーティングシステム(Windowsなど)、Webサーバー(IISなど)、およびASP .NETのさまざまなコンポーネントによる要求の最初の受信などを省略しているため、ASP .NET MVCアプリケーションの部分的な表現に過ぎません。 HTTP要求がASP .NET要求処理パイプラインを通過する際の処理を担当します。これらの事項は、この説明のために省略することができる。呼び出しグラフの最上位に座ることに注目する価値はありますが、HTTP要求を処理する初期段階を処理し、最終的にはいつかはASP .NETが最終的にコントローラのアクションを呼び出します。

図から分かるように、私はASP .NETによって非同期アクションとして呼び出されるコントローラの動作を表しています。コールグラフの左側には、一連の非同期プロシージャコールがあります。最終的にあなたの質問の対象となるボックスに到着します。

"すべての方法でダウン"という概念と一致する質問に対する答えは、 "私は非同期の方法です"ということです。この非同期メソッドは何をしますか?それはあなたがしたいことにかかっていますか?ファイルを読み書きしている場合は、ファイルを読み書きする非同期呼び出しです。データベースクエリを作成していますか?次に、そのクエリを行う非同期メソッドへの呼び出しです。これを念頭に置いて、IOドライバを非同期的に実行するデバイスドライバメソッドが最下部にあることがよくあると言えるでしょう。これは、画像やビデオファイルの処理など、実行したいと思っている、長時間実行される計算上の非同期操作であることは簡単です。

ここでもコールグラフの右側に注目する価値はあります。非同期メソッドを完全に呼び出すことがよくありますが、このコールグラフの右側の分岐は、必ずしも一番下の非同期メソッドを呼び出す必要はないことを示しています。 enter image description here

6

GetRecordsFromDbAsyncは非同期メソッドなので、非同期サポートASP.NET Webサーバーによって呼び出されるトップレベルの非同期メソッドは、非同期を次のレベルに渡します。

GetRecordsFromDbAsyncまで、またはその子孫が実際にコールスタック内の最後の非同期メソッドを実際に呼び出します。そこにはおそらくネイティブになり、ファイルが読み込まれたときに呼び出されるI/O割り込みやその他のものが登録されます.Webリクエストは処理されます。

12

すべての方法でWin32 APIになります。そのレベルでは、非同期I/OはOVERLAPPEDオブジェクトを介して実行され、WaitForMultipleObjectsExなどの警告可能な待機が行われます。それは通常、あなたが非同期メソッドを使用したら、あなたはバック(またはまでのすべての方法の非同期メソッドを持っている必要があるという事実を指しているため

+0

提供できるリンクはありますか?もしそうなら、私はおそらく最良の答えとして選ぶでしょう。 – user7127000

+0

@ user7127000ここに素敵なブログ記事が掲載されています: http://blog.stephencleary.com/2013/11/there-is-no-thread.html –

16

「ダウンすべての方法の非同期」というフレーズは、少し誤解を招くおそれがあり、あなたの精神的なイメージに依存します) - 非同期メソッドから呼び出し元まで、そしてあなたの呼び出し元の呼び出し元など。

この例では、asyncタスクを公開するWebApi/MVCコントローラを示しています。 asyncチェーンの次のステップは、WebApi/MVCインフラストラクチャで、HTTP GET要求を受信し、それをコントローラにマップし、コントローラのメソッドに呼び出しをディスパッチします。このインフラストラクチャはasyncに対応しています。つまり、asyncコントローラメソッドを正しく呼び出すことができ、awaitという結果がHTTP応答を返すことがわかります。

インフラストラクチャがどの程度正確に実装されているかについては、具体的にはわかりませんが気にしません。ASP.NET Webサービスはコントローラasync Taskをサポートしています。

+6

私はこの言葉の表現が "それは類似のアナロジーをサポートしているので、それはすべての方法でダウンカメです "。 –

+0

真実なので、混乱します。 –

4

あなたの質問から、引用が見つかった場所や使用されている文脈が明確ではありません。しかし、 "async all down down"は、通常、単一の論理操作で同期メソッドと非同期メソッドの間を行き来する必要がないことを意味すると理解されています。

何かが非同期で実行される場合、それは(アップと)一貫「すべての方法ダウンし、」すべてのレベル、これで非同期、は、/ etc階層/コールスタックでなければなりません。言い換えれば、非同期コードの任意のポイントで同期ブロッキング呼び出しを行うことは絶対に意味がありません。なぜなら、実際に非同期ではないからです。 .NET並列プログラミングチームのブログエントリから

"Should I expose synchronous wrappers for asynchronous methods?"

非同期絞っ

ここでのポイントは、あなたが同期非同期APIをラッピングする際に非常に注意する必要があるということですあなたが慎重でないかのように、あなたは本当の問題に遭遇する可能性があります。同期呼び出しを期待しているものから非同期メソッドを呼び出す必要があると思っている場合(たとえば、同期メソッドが実装されているインターフェイスを実装している場合など)、そのインターフェイスを実装するには、非同期で公開されている)、まず本当に本当に必要であることを確認します。このパスまたはコードパスを上から下に非同期に再配置するのではなく、「同期オーバー非同期」をラップする方が便利かもしれませんが、リファクタリングは可能な場合にはより良い長期的ソリューションになることがよくあります。

あなたの質問は、.NETソースコードのMSalters has already answered thisで確認できます。基本的に、.NET APIは、Windowsオペレーティングシステムによって提供されるシステムレベルのAPIを呼び出します。これらは非同期I/Oを実行し、完了したときに発信者に通知します。しかし、これが技術的なレベルでどのように機能するかを理解する必要はありません。それは抽象化の全体のポイントです。

+0

あなたが提供したリンクは便利でした。どこから「async all way down」が来たのかは、Stephen Clearyが書いたhttps://msdn.microsoft.com/en-us/magazine/jj991977.aspxの記事から来ていると思います前。 –

+0

ああ、それはまた素晴らしいリンク@Darrenです。あなたの答えにそれが含まれていないのはなぜですか? :-) –

+0

私は、Clearyの記事で意味されていたことを理解するのに役立つ、おじさんのボブのコールグラフの描画を黒板に発見したからです。 –

関連する問題