2

C#で記述されたライブラリを使用するC ++/CLIで記述されたアプリケーションがあります。このアプリケーションは、標準のソケットAPIを使用して作成され、select()を使用して通常の非同期ソケットの束を多重化します。ただし、サードパーティのライブラリは.NETソケットを使用し、非同期の結果とコールバックを使用します。

シナリオは次のとおりです。メインスレッド(主にネイティブスタイルのコードを使用するC ++ / CLIアプリケーション)に一連の通常のソケットを作成します。サードパーティのライブラリベンダーのC#「セッション」オブジェクトを作成します。このオブジェクトには、内部で.NETクラスの非同期ソケットが多数含まれています。

私が気付いたのは、C#の「セッション」オブジェクトをインスタンス化するメインスレッドのselect()にNULLタイムアウトパラメーターを設定すると、.NETソケットに対して非同期コールバックがまったく行われないことです。たとえば1秒のタイムアウトを使用し、非同期ソケットで他のアクティビティが発生しない場合、select()がタイムアウトするまで非同期ソケットコールバックは配信されません。

どういうわけか、select()は.NETソケットに対してコールバックが発生するのを防いでいます。これを回避するにはどうすればよいですか?.NETソケットが非同期コールバックを配信できるようにする古いソケットに使用できる代替のポーリング方法はありますか?

4

1 に答える 1

0

解決策を見つけました。

.NET で使用される AsyncCallbacks では、send()/recv() 関数を含め、ブロックする関数をまったく持つことはできません。非ブロックであっても [1] (少なくとも私自身のテストによると)。ブロッキング関数が AsyncCallback で呼び出された場合、動作は未定義です。コードからこの「未定義性」を取り除くと、物事は正常に機能し始めました。

select() を WaitForMultipleObjectsEx() に交換するいくつかのポリシー クラスを作成してクラスを再テンプレート化し、AsyncCallback に SetEvent() を配置して多重化をトリガーすることで問題を解決しました。これでほとんどの問題は解決したようです。

[1] 編集: 以下のコメントを参照してください。send() をノンブロッキングまたはブロッキングソケットで使用したかどうかは、「物事を壊す」ことと未定義の動作に入るという点で違いがあるようには見えませんでした。

于 2012-08-10T18:03:53.733 に答える