Socket.SendAsyncスレッドは効果的に安全ですか?
-
22-07-2019 - |
質問
SilverlightのTCP通信をいじっていたため、System.Net.Sockets.Socketクラスを使用せざるを得ませんでした。Silverlightランタイムには非同期メソッドしかありません。
2つのスレッドが1つのソケットインスタンスで非常に短い時間で1つのソケットインスタンスでSendAsyncを呼び出すと、どうなるのかと思っていましたか?
心配しているのは、TCPチャネルを通過するバイトが混在しないことです。
非同期メソッドである私は単一のスレッドがデキューするキューにメッセージが置かれるので、そのようなことは起こりません(メッセージの内容が混在する)。
しかし、私は確信できず、MSDNはメソッドの説明に何も記載していません。誰もこれを確信しているか?
EDIT1:いいえ、SendAsyncを呼び出す前にオブジェクトをロックします:
lock(this._syncObj)
{
this._socket.SendAsync(arguments);
}
これは、実際に送信されたデータではなく、データを送信するリクエストをシリアル化するため、役に立ちません。
解決
SendAsync
を呼び出すには、まず SocketAsyncEventArgs
のインスタンスで ConnectAsync
を呼び出す必要があります。クライアントとサーバー間の接続を表す SocketAsyncEventArgs
のインスタンス。 SendAsync
の未処理の呼び出しに使用された SocketAsyncEventArgs
の同じインスタンスで SendAsync
を呼び出すと、例外が発生します。
同じ Socket
オブジェクトの SendAsync
に対して複数の未解決の呼び出しを行うことができますが、 SocketAsyncEventArgs
の異なるインスタンスのみを使用します。たとえば(これが必要になる可能性があるパラレルユニバースの場合)、同じサーバーに同時に異なる接続で複数のHTTPポストを作成できます。これは完全に受け入れられ、通常、クライアントもサーバーもどのパケットがどのパケットであるかについて混乱することはありません。