2016-11-10 1 views
1

私はasp.Net MVCでC#でasync/awaitを使用する方法を理解しようとしています。 主なポイントは、IOを実行しているときにワーカープールからスレッドを解放するためにasp.netが役立つためです(他のものを処理できるようになります)。そうするためには、非同期/待機モードの修飾子をIOコールからコントローラアクションまでのメソッドから昇格させる必要があります。コントローラに昇格しないと、なぜasyncを使用しますか?

コントローラの非同期/待機をプロモートせずにこの機能を使用することには何らかのポイントがありますか? (たとえば、Asyncメソッドの呼び出しの後にTask.Waitを追加するなど)。

+0

基本的には、ホストシステムが非同期コードの場合と同じことを基本的に手作業で行っている場合、他のタスクが実行されている間にそれを行うことができます。それはかなり複雑かもしれませんが、実行可能です。非同期にはまったく魔法がありません。これは主に、最下位のコードが他のことを実行できるようにし、最下位のインフラストラクチャコードが何かを完了するのを待つ方法です。ホストシステムはトップレベルでサポートしていますが、コードでもサポートしています。しかし、シンクロナイズドオペレーションの背後にある非同期オペレーションを単純に「隠す」のであれば、本質的に利益を無効にします。 – David

答えて

2

回答は「はい」ですが、アクション内でTask.Wait()を使用することは、デッドロックの原因となる可能性があるため、お勧めできません。

、ガイドからStephen ClearyによってAsync/Await Best Practiceを次のように考えてみましょう:

図3 Aの一般的なデッドロックの問題あなたがConfigureAwait(false)を追加する場合は、しかし、非同期コードに

public static class DeadlockDemo 
{ 
    private static async Task DelayAsync() 
    { 
     await Task.Delay(1000); 
    } 
    // This method causes a deadlock when called in a GUI or ASP.NET context. 
    public static void Test() 
    { 
     // Start the delay. 
     var delayTask = DelayAsync(); 
     // Wait for the delay to complete. 
     delayTask.Wait(); 
    } 
} 

をブロックDelayAsync()このように:

記事で説明したように

、あなたは、デッドロックを回避することができます

を別にパフォーマンスから、ConfigureAwaitは別の重要な側面を持っている:それはデッドロックを回避することができます。 図3を再度検討してください。 DelayAsyncのコード行に "ConfigureAwait(false)"を追加すると、デッドロックが回避されます。今回は、待機が完了すると、スレッドプールコンテキスト内でasyncメソッドの残りの部分を実行しようとします。メソッドは完了することができます。返されたタスクは完了し、デッドロックはありません。このテクニックは、アプリケーションを徐々に同期から非同期に変換する必要がある場合に特に便利です。

+0

私がよく理解すれば、私の質問に対する答えは「あなたはそれを促進しなければなりません」ということですか?デッドロックの問題のため –

+0

絶対にはい:) –

0

デッドロックまたはAggregateExceptionを生成する可能性があるため、Task.Waitは使用しないでください。これを行う必要がある場合は、非ブロックであるTask.WhenAllを使用する必要があります。

一般的に、非同期コードをエンドツーエンドで使用するのが最も安全です。スタック全体でasyncを使用する利点は、コードのデバッグが容易でエラー処理がずっと簡単なことです。

so yes async/awaitを使用する場合は、コントローラーに組み込み、Task.Waitなどのブロックコードを使用しないでください。

関連する問題