4

私は自分で作成していないコードを調べており、アプリケーションがクラッシュする原因を理解しようとしています。

おそらく、リソースの処理方法とスレッドの管理方法にかかっていると思います。

メインの親スレッドは、新しいアプリケーション層クライアント(TCPMonitor)を作成し、次にTCPソケット通信(TCPListen)を処理する別のクラスを作成します。このクラスは、新しいTCPソケットクライアントとそのソケット上の読み取りネットワークストリームを作成する新しいスレッドループを生成し、同期ブロッキングRead()を呼び出します。

ただし、ネットワークエラー接続が発生した場合、例外はTCPListenスレッドループでキャッチされ、イベントが所有クラスTCPMonitorに戻されます。次に、TCPMonitorは、アクティブなTCPListenインスタンスを保持しているかどうかを確認し、保持している場合はDispose()を呼び出して、インスタンスをNullに設定します。

この時点で、TCPListen Read()はまだ確実にブロッキング呼び出しにありますか?その場合、親スレッドからDisposeを呼び出すと、子スレッドがブロッキング呼び出しから切り離され、ストリームとソケットが適切に破棄されるようにするにはどうすればよいですか?

4

3 に答える 3

1

コードが使用している実際のC#ネットワークAPI呼び出しについては言及していませんが、基になるSocketオブジェクトの多くの「Receive」メソッドの1つであると仮定すると、バインドされた接続ソケットで無期限にブロックされない限り、正しくブロックされます。Socketオブジェクトにタイムアウトが設定されます(ReceiveTimeout )。

一度設定すると、その時間内にデータが受信されない場合に戻ります。次に、Receieve呼び出しを、スレッドを停止するようにトリガーするように外部で設定できるブール値のループに入れることができます。

アップデート:

同期Read呼び出しでスレッドをブロックする代わりに、DataAvailableを使用してループ内のNetworkStreamにクエリを実行し、代わりに読み取るものがあるかどうかを確認できますか?

于 2012-09-12T09:45:52.653 に答える
1

呼び出しをブロックする代わりに非同期呼び出し(たとえばBeginReceive)を使用し、スレッドにオブジェクトを待機させて、オブジェクトを正常に終了するように指示するのはどうですか?aのようなものを作成しManualResetEvent、スレッドに待機させます。メインスレッドからイベントを通知し、リスニングスレッドがウェイクアップすると、ソケットを閉じることができます。

コールバックデリゲートがデータを使用して呼び出されたときにBeginReceive、スレッドがさらにデータを受信する必要がある場合は、への別の呼び出しを行う必要があることに注意してください。BeginReceiveここの説明を確認してください:http: //msdn.microsoft.com/en-us/library/dxkwh6zw

于 2012-09-12T10:13:36.070 に答える
1

入力用のソケットをシャットダウンします。これにより、読み取りのブロックが解除され、APIで使用される形式に関係なく、EOS表示が取得されます。Windowsを使用しているため、送信を続けると、もう一方の端も接続を停止します。(この動作はプラットフォームに依存します。)

于 2012-09-14T22:30:19.767 に答える