2009-04-06 28 views
0

MFC CAsyncSocketを使用して、マルチスレッド環境でネットワーク通信を行っています。受け入れられたソケットに入ってくるデータを受け入れるのに数時間をかけた後、CAsyncSocketのOnReceive関数を呼び出すために、ソケットはメインのGUIスレッドのコンテキスト内になければならないというページが出てきました。メインのGUIスレッドに移動すると、ソケットのデータ受信が開始されました。CAsyncSocketとスレッド

私の質問はこれです:誰でもこれの回避策を知っていますか?以前はソケットがGUIスレッド上にあり、OnAcceptが正常に呼び出されていました。受け入れられたソケットはデータを送信するために使用でき、何も受信できませんでした。もし私がそれを避けることができれば、ソフトウェアのこの部分を再構築する必要はありません。

答えて

3

ソケット用の独自のメッセージキューを持つ別のスレッドを作成する方が簡単でしょうか?私はCAsyncSocketをメインメッセージキューに作成する必要があるとは思わない、ちょうどいくつかのメッセージキュー。独自のMFC互換のメッセージキューを持つ別のスレッドを作成する方法については、CWinThreadのマニュアルを参照してください。

残念ながら、新しいスレッドのコンテキストからすべてのソケット操作を呼び出すことは非常に重要です。 MFCはスレッド単位の情報を保持するスレッドローカルストレージを使用する隠しクラスでグローバルな状態を使用し、その情報は多くのCAsynchSocketのメソッドで使用されます。これは、CAsynchSocketがスレッドアフィニティを持っていることを意味し、メッセージポンプとなるスレッドであれば常に使用して作成する必要があります。

CWinThreadを作成し、そのスレッドのコンテキストでウィンドウを作成して独自のカスタムMFC隠しウィンドウを作成し、そのウィンドウにすべてのソケット用のメッセージとメッセージハンドラを作成する方法があります操作(作成、接続など)を行うことができます。スレッドがメッセージをポンピングしていることを確認してください( "Run()"メソッドがこれを行います)。そしてあなたのソケットを制御するためにウィンドウにメッセージを投稿/送信してください。

また、ソケットからのコールバックは、UIまたはワーカースレッドとは別のスレッドで取得されることに注意してください。 GUIオブジェクトを更新している場合は、競合状態やおそらくGUIスレッド親和性の問題を心配する必要があります。

デザインの影響が心配な場合は、独自のCThreadSafeAsynchSocketプロキシオブジェクトを作成し、非表示ウィンドウへのメッセージの受け渡しを通じて実際の実装に委任してください。ブロッキング操作にはSendMessage、非同期操作にはPostMessageを使用できます。ファクトリオブジェクトにコンストラクタをラップすると、必要になるまでソケットスレッドの作成を遅らせることができます。

私が考えることができる最後の懸念は、すべてのプロキシが消えてスレッドをシャットダウンしたときに検出する必要があることです。 CThreadSafeAsynchSocketのコンストラクタ/デストラクタによって管理されるグローバル参照カウントを使用して、スレッドをいつシャットダウンするかを検出できます。スレッドをシャットダウンしないと、メインのアプリケーションウィンドウを閉じた後でも、隠されたウィンドウが表示されたままになります。

+0

私の元のコードでは、メッセージポンプ付きのスレッドが使用されていましたが(テストされ、ソケットを介して送信されています)、依然としてOnReceiveを呼び出すことはできませんでした。 – Noaki

+0

隠されたウィンドウで本格的なGUIスレッドを試してみてください。 –

関連する問題