2013-07-05 4 views
43

C#でどのように非同期動作が待っているのか理解しようとしています。私はawaitキーワードを使用するどのメソッドも非同期でマークする必要があることを理解しています。 キーワードがawaitの行がヒットした場合、その行の下のコードは実行されません。非同期操作が開始され、待機中の行のステートメントを実行し、実行を続行できる呼び出しメソッドに制御が戻されます。どのようにC#で非同期動作を待つのですか

質問#1:この仮定は正しいのですか、awaitキーワード以下のコードがまだ実行されていますか?

第2に、非同期のサービスメソッドを呼び出し、その結果を返す必要があるとします。 return文はawaitキーワードの下にあります。

質問#2:非同期呼び出しが完了した後、またはその前にreturnステートメントがヒットするのはいつですか?

質問#3:そのサービスコールの結果を使用したいと思います。非同期操作は役に立たないので、結果が返されたときに呼び出しメソッドがヒットするようにしてください。これは、呼び出しsynchronusを行うResultプロパティを使用して行うことができることを理解します。しかし、DB操作で非同期を使用すると、実際にはほとんどのアプリケーションで時間の80%を占めることになります。

質問#4:DB操作で非同期を使用するにはどうすればよいですか?それは可能であり、推薦されていますか?

質問#5:scenraioが非同期操作を便利にするのは、すべてのAPIが理由なく非同期操作を行っているようです。または私は非同期操作を使用するポイントを逃したのですか?

私は、理由がなくてもメソッドが何かを返さなければならないので、APIのasynメソッドを作っていると言っていることを意味し、その計算が行われるまでどのように彼らは本当にそれを意味する結果が返されるまで役に立たないでしょうか?

+4

あなたはかなりの質問をしています。 1つの集中的な質問をするのが最も効果的です。複数の質問がある場合は、別々に投稿してください。 – svick

+20

@svick何とか混乱した初心者のための非常に丁寧なコメントではありません。とにかく彼は5つのことを尋ねますが、実際には、非同期/非同期の意味と有用性を重視しています。 –

+1

@Svick私はそれを見る方法をMDSNはさらに混乱させ、私の心の中に多くの質問を残しました。他の誰かが同じ問題を抱えているなら、おそらく彼らはこのスレッドを見ることができ、非同期操作をより良く理解することができます。私のすべての質問は1つのトピックに関連しています。私には5つの異なる質問を投稿し、誰かがそれらのすべてを見ることを願っていません... –

答えて

43

MSDN explains everything

バニラのドキュメント(特にMSDNのドキュメント)は、特定の状況に適用するのが難しい場合がありますので、ご理解ください。

質問#1:この仮定は正しいのですか?awaitキーワードの下のコードはまだ実行されていますか?

"await"キーワード以下のコードは、非同期呼び出しが完了したときにのみ実行されます。その間、あなたのメソッドは "非同期"とマークされているので、メソッドが完了するまでコントロールはメソッドの呼び出し元に返されます。私はコメントは非常に説明されていると思います

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; 

:上記のMSDNのリンクから 。

第2に、非同期のサービスメソッドを呼び出し、その結果を返す必要があるとします。 return文はawaitキーワードの下にあります。

質問#2:非同期呼び出しが完了した後、またはその前にreturnステートメントがヒットするのはいつですか?

質問#3:そのサービスコールと非同期操作の結果を使用したい場合は、結果が返されたときに呼び出すメソッドをヒットさせる必要があります。これは、呼び出しsynchronusを行うResultプロパティを使用して行うことができることを理解します。しかし、DB操作で非同期を使用すると、実際にはほとんどのアプリケーションで時間の80%を占めることになります。

サービスを完了するために3つの無関係のDBクエリを作成し、その結果に基づいて計算を実行して終了するとします。これを順次実行した場合は、各操作が完了するまで待つ必要があります。非同期呼び出しを使用すると、C#は3つのクエリを並行して実行し、サービスはずっと早く終了する可能性があります。

また、Taskを返す操作をFuturesとして使用することもできます。先物に基づいて作業を並列化して結果をマージする方法については、いくつかのパターンについて説明していますMSDN on Futuresを参照してください。

あなたのサービスが1つのDBコールしか必要としないなら、間違いなく非同期と呼ぶことは間違いありません。

質問4:DB操作で非同期を使用するにはどうすればよいですか?それは可能であり、推薦されていますか?

ここで、ADO.NETには非同期メソッドReadAsync and NextResultAsyncが含まれています。

このディスカッションは、私がhereと書くよりはるかに完全である可能性があります。

質問#5:scenraioは非同期操作が役に立ちますが、すべてのAPIが理由なく非同期操作を行っているようです。または私は非同期操作を使用するポイントを逃したのですか?

非同期操作は、スレッドの問題に遭遇することなく、長い実行中の操作を簡単に並列化するのに非常に便利です。あなたのメソッドがただ一つのこと、またはシンプルな(高速な)もののシーケンスを実行する場合、はい、非同期にするのは無駄です。しかし、長時間実行される操作が複数ある場合は、スレッドを管理するよりもはるかに簡単で、非同期で並列化する方がエラーが少なくなります。

+1

うわー!おかげで、あなたはすべてを非常に分かりやすい方法で説明しました。私はMSDNを使いましたが、どのラインがいつ実行されるかを説明する数字がたくさんあるダイアグラムを見て、私はさらに混乱させました。お返事をありがとうございます! –

+0

引用符で囲まれたコードは、引用符で囲まれたコードに定義されていない/含まれていない "AccessTheWebAsync"を参照しています。それがコンテナメソッドであると仮定します。 – Manachi

14

あなたの質問の多くは、私が書いたofficialdocumentationan intro postに返信されています。

質問4:DB操作で非同期を使用するにはどうすればよいですか?可能であれば

エンティティフレームワーク6(現在ベータ版)はasyncをサポートしています。下位レベルのデータベースAPIは、ある方法または別の方法で非同期操作をサポートします。それらの一部(例えば、SQLite)はasyncを直接サポートします。他の人は簡単なasync互換ラッパーを書く必要があります。

...とお勧めしますか?

バックエンドのスケーラブルでない単一のデータベースマシンと通信するフロントエンドサーバー(たとえば、ASP.NET)を作成している場合を除き、あります。その特定のケースでは、バックエンドはそれに合わせて拡大縮小することができないため、フロントエンドスケールを作成することに意味はありません。

質問#5:scenraioは非同期操作が役に立ちますが、すべてのAPIが理由なく非同期操作を行っているようです。または私は非同期操作を使用するポイントを逃したのですか?非同期操作の

利点は以下のとおりです。

  1. クライアント(UI)側では、アプリケーションが応答のまま。
  2. サーバー側では、アプリケーションの拡張性が向上します。
+0

あなたの答えの終わりに、単純ではあるが完璧に述べられた利点があります。 – joelc

関連する問題