2012-04-13 21 views
10

Socket.BeginSend()メソッドを検討してください。 2つのスレッドプールスレッドが同時にこのメソッドを呼び出すと、それぞれのメッセージが互いに混ざり合うか、ソケットクラスがこれを起こさないようにしますか?ソケットスレッドへの非同期書き込みは安全ですか?

+1

動作しますが、UDPのような信頼性の低い注文データグラムベースのプロトコルでのみ行う必要があります。その理由は、2つのスレッドがBeginSendを呼び出すためにレースしている場合、送信元で順序が乱れることがあります。これにより、TCPを使用しているときにアプリケーションデータが破損する可能性があります。 –

答えて

7

私はあなたの質問に答えているような賢いpost on the MSDN forumを見つけました。

  1. 複数のBeginSendを同時にキューに入れることができます。あなたは、ロックする必要はありません

編集:

さらに興味深い情報:

あなたはRemark section of the MSDN doc BeginSend()内のビットをスクロールダウンした場合、あなたはコールバックの興味深い用途が見出されるであろうあなたに関連する可能性のある方法。

[...] BeginSendメソッドを呼び出した後に元のスレッドをブロックする場合は、WaitHandle.WaitOneメソッドを使用します。 [...]

+1

私はこれを知らなかった、ありがとう! – covertCoder

+1

これは私が探していたものです!ありがとう! – Dabloons

11

.NETソケットインスタンスは、いくつかのメソッド(同じものまたは異なるもの)を同時に呼び出すと、一貫性のない状態が発生する可能性があるため、スレッドセーフではありません。しかし、BeginSend()およびBeginReceive()のメソッドは、スレッド自体に対してに対して安全です。

複数の未処理のコールをそれぞれ(またはその両方)呼び出すことは安全です。

BeginReceive()の場合は、データが呼び出される順番で利用可能になるとサービスされます。これは、処理時間がかかるなど、できるだけ早く他の受信が行われるようにする場合に便利です。もちろん、この場合、複数の領収書を同時に処理するコードがあり、独自の同期ロジックが必要な場合があります。

BeginSend()の場合、各呼び出しは送信されたデータをソケットバッファにプッシュしようとし、そこで受け入れられるとすぐにコールバックが呼び出されます(EndSend()と呼ばれます)。呼び出しに必要なバッファ領域が不足していると、ブロックされます。

注:

  1. 8Kです:デフォルトの8Kバッファは、以下に該当するとして、「私はすぐに、それはブロックします、正確に8KのデータをBeginSend()を呼び出すことができる」を意味することを想定していません。あなたが通話の8K価値をアップqueingされている「公称サイズ」数、およびバッファが縮小し、やや

  2. を育てることが、データが縮小ネットワーク上で送信されることになるというキューイングされたデータの8K

一般的には

:あなたがスレッド内BeginSend()複数回呼び出す場合

  • 、あなたは彼らが呼ばれた順番にマシンを残して送信していることが保証されています。

  • 複数のスレッドからBeginSend()を呼び出すと、実際の呼び出しが特定の順序で発生するように他のブロックメカニズムを使用しない限り、順序の保証はありません。ただし、各呼び出しは、ネットワークバイトの1つの連続したストリームで適切にデータを送信します。

+0

あなたの答えは最初の質問の数年後に来て、私はちょうどそれを見ています(もう1年後)が、それは素晴らしい詳細を持っていたことを知り、本当に感謝します。しかし、.Netフレームワークの私の個人的な知識と開発者としての私のスキルは今この質問をはるかに過ぎていますが、この答えは将来の読者のための大きなリソースになるでしょう。私が何年も前に正しい答えとして答えをチェックしていなかったなら、あなたに正しい答えを与えるでしょう。とても有難い。 – Dabloons

関連する問題