26

この単純な質問に対する答えを見つけるのに合理的と思われるよりも多くの時間を費やした後、他の人が私がたどったばかりのすべてのフープと間違った道をジャンプする必要がないように、ここに結果を残すことにしました.

問題は、TcpClient の ReadTimeout プロパティを使用していて、読み取り操作が実際にタイムアウトした場合、Microsoft がソケットを閉じることにしたことです。これは、私が知っている他のソケット実装では予期されておらず、望ましくもありません。また、プログラマーの怠惰以外に、これが当てはまる正当な理由はありません。しかし、これは Microsoft が選択したことです。

とにかく、このサイトを含め、私が見つけたすべての回避策には、何らかの形式のビジー ポーリングを実行するさまざまな方法があり、単純な読み取り呼び出しを実行するためにさらに別のスレッドを開始する方法さえありました。申し訳ありませんが、特に多くのソケットが開いている状態で、そこに座ってポーリングするよりも、CPU を使用する方が良いことがあるため、これはオプションではありません。結局のところ、これは 1990 年代の初めのように、忙しいポーリングが単に物事を行う方法であったわけではありません。今日では、オペレーティング システムと呼ばれるものがあり、割り込みを使用してこれらの種類のことを非常に効率的に処理します。

とにかく、さらに別の接線検索で、この古いブログ投稿に出くわしました。

http://blogs.msdn.com/b/mflasko/archive/2006/02/20/535655.aspx

MSDN ブログ > Mike Flasko のブログ > ネットワーク データの読み取り時のタイムアウトの処理

読み取りタイムアウトを適切に処理する方法に関する解決策を示す重要なポイントは次のとおりです。

この時点で、例外をキャッチしてから、同じ NetworkStream で読み取りを再発行したくなるかもしれません。この戦略は、予期しないエラーにつながる可能性があります。最善の方法は、NetworkStream (ソケット) を不安定な状態として扱うことです。これは、基礎となるスタックがタイムアウトになると、基礎となる I/O 読み取りがキャンセルされるためです。データが同時に入ってくると、データが失われ、データ ストリームが破損します。

そして解決策:

より良い方法は、例外をキャッチし、ソケットまたは TCPClient を閉じて、必要に応じて再接続することです。

これはAPIのユーザーに不必要な負担をかけると思いますが、少なくとも、半適切なソケットReadTimeoutを実行する方法を見つけようとして調べた数十のサイトから見つけた最も適切な解決策です.

この質問/コメントが、私が見つけるのにかかった時間を節約してくれることを願っています.

4

1 に答える 1

2

探しているのは Poll または Select メソッドです。これらにより、基になる接続を閉じずにタイムアウトでデータを待つことができます。

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.poll%28v=vs.110%29.aspx http://msdn.microsoft.com/en-us/library /system.net.sockets.socket.select%28v=vs.110%29.aspx

于 2014-02-14T16:40:43.800 に答える