2012-03-06 16 views
7

これは、MSDN hereに記載されているC#.NETの非同期パターンに関する一般的な質問です。C#.NETでは、非同期操作では必然的にブロックするスレッドが作成されますか?

同期操作を呼び出す必要がある場合(たとえば-WCF、DBクエリ、IOなど)、スレッドをブロックしたくない場合(GUIスレッド)、これは意味しますかブロッキングを行う別のスレッドがどこかに存在している必要がありますか?

は必ずしもブロックするようにどこかのスレッドを必要と同期コール非同期を作っていますか?

したがって、私が長時間実行している非同期呼び出し(実際には10同期呼び出し)を行う場合、待機中のスレッドは10個必要ですか?または、10スレッドがブロックされないようにするメカニズムはありますか?

WCFでは、WCF呼び出しのBeginメソッドとEndメソッドを作成して非同期にすることができます。これは、私がこの非同期メソッドを呼び出すと、クライアントまたはサーバーのどこかにスレッドがあり、それが私を待っていることを意味しますか?

私は、非同期を達成するためのさまざまな方法についていくつかの記事を読んでいますが、これらの記事では、何がボンネットの下で行われているのか説明していません。

更新

私は.NETの興味についての詳細ですので、私は、私の質問は、より多くのspecifcました。 MSDNによって記述される非同期パターン。

アップデート2

私は同期呼び出しを非同期に行うにも、より具体的に質問を改革しました。

答えて

7

.NETフレームワークでは、スレッド、スレッドプール、BeginXxxおよびEndXxxメソッド、イベントベースのAPM、またはタスクベースのAPMを使用して、非同期操作を実装する方法が多数あります。

各非同期パターンは、独自の内部実装を持っており、これらすべての非同期プログラミングモデルは、伝統的なBeginXxxとEndXxx非同期パターンを含む、このブログarticleで説明されています。以下は

は、クイックリファレンスのためのすべての非同期パターンの概要です: Async Summary:

また、ジェフリー・リヒターもうまくMSDNマガジンでCLR Asynchronous Programming Modelを説明します。

+0

グレートリンクを確認することができます詳細については、完了するのを待っている任意のスレッドがあって文句を言いません。したがって明示的にはそうは言いませんが、低レベルの非同期呼び出しのように見えますが、これはスレッドをブロックすることなく行われます。しかし、同期呼び出しを非同期にする場合は、スレッドを作成する必要があります。私はこれについて正しいですか? – Mas

+0

@Mas 'Thread'を作成することは、非同期にする唯一の方法です。要約で説明したように、同期呼び出しを非同期呼び出しに変換する他の方法もあります。 – VS1

+0

この表によれば、すべての非同期パターンはスレッドに基づいています(タスクはバックグラウンドでスレッドも使用します)。 – Mas

2

残念ながら、これには一つの答えはありません。ライブラリの中には、ソケットなど、ハードウェアでサポートされているような、ネイティブに実装された非同期操作を提供するものがあります。そうでない人もいるかもしれません。サードパーティ製のライブラリがとてもうまくブロックされているようです。

3

操作ごとに1つのスレッドである必要はありません。 @ Ioannis Karadimas氏によると、これは実装によります。

たとえば、10個の異なるソケットからの非同期受信をしたいとします。これは、メッセージを受信したときに使用可能な1つのソケットを非確定的に選択するループで選択する呼び出しを使用して、1つの余分なスレッドで実現できます。

2

'長時間実行される非同期呼び出しを10回実行すると、待機中のスレッドが10個必要ですか?'一般的に、いいえ。

'または10スレッドがブロックされないようにするメカニズムがありますか?' - 1つのブロッキングスレッドが複数のアイテムを処理できるようにするメカニズムがあります。簡単な例 - カーネルスレッドは、NIC信号と入力キューセマフォを待つかもしれません。通常、それらはどちらか一方を待ってブロックされます。あなたの非同期ユーザアプリケーションはネットワーク送信をキューに入れ、カーネルスレッドはそれをキューから取得し、それをネットワークカードハードウェアに送信しようとします。それができない場合は、それを内部の送信キューに追加し、 'WOULD_BLOCK'返信であなたのアプリに戻ります。ハードウェアが準備が整うと、カーネルスレッドは、送信バッファをデキューし、ハードウェアにロードします。同様に、あなたのアプリはrecv()の非同期リクエスト(バッファ付き)を1つ以上送信し、カーネルスレッドはそれをリストに追加し、 'WOULD_BLOCK'返信で返します。データがNICに入ると、そのドライバ信号とカーネルスレッドがデータを検査し、そのデータを待っているリスト内のエントリを見つけようとします。あなたのアプリケーションのデータであれば、ハードウェアからバッファにデータをコピー/ DMAし、非同期コールバックを呼び出します(asycnコールバックがどのように呼び出され、どのスレッドでOSに依存しているかに注意してください。あなたのGUIスレッドにキューイングされているか、IOCP補完構造体がユーザースレッドプールにキューイングされています)。

とにかく、要点は、カーネルスレッドが、内部送信リストまたはrecvアイテムリスト内の多くのプロセスから多くのエントリを持つことができるということです。ハードウェアまたはその入力キューに注意が必要な場合は常に実行され、処理されます。それ以外の場合はブロックされたままです。

1

いいえフレームワークライブラリを使用して非同期呼び出しを行うと、スレッド待ちはありません。たとえば。あなたのユースケースでは、 を挙げています。「WCFでは、WCF呼び出しのBeginとEndメソッドを作成して非同期にすることができます。これは、この非同期メソッドを呼び出すと、またはサーバー、それは私を待っているのですか? "

非同期操作はあなたが記事にこの素晴らしいブログに http://blog.stephencleary.com/2013/11/there-is-no-thread.html

関連する問題