16

私は NetworkStream と TcpClient を使用して、BeginRead を使用してデータを非同期に受信しています。指定した時間が経過すると読み取りが中止されるように、この操作にタイムアウトを適用する必要があります。

私が知る限り、これは NetworkStream または TcpClient ではサポートされていません - ReceiveTimeout プロパティがありますが、これは同期に相当する「読み取り」にのみ適用されるようです。

基になる Socket クラスでさえ、その BeginReceive メソッドでタイムアウトをサポートしていないようです。

この問題について検索したところ、タイムアウト期間内に操作が完了しない場合に操作をキャンセルする別のバックグラウンド スレッドをセットアップするという唯一の解決策が提案されました。これは恐ろしいハックのようです。きっともっと良い方法がありますか?

4

2 に答える 2

2

これが唯一の方法です。非同期操作を使用している場合、操作を開始したスレッドは別のことをしているからです。Read操作が完了するまで実行スレッドがブロックされるため、タイムアウトは同期バージョンで使用できます。

ただし、操作をキャンセルするためにバックグラウンド スレッドを使用する必要がある場合は、非同期の Begin/End メソッドを引き続き使用しても意味がありません。バックグラウンド スレッドをスピンオフする場合は、バックグラウンド スレッドから同期読み取り操作を実行するだけで、ReceiveTimeout を使用できます。

于 2011-04-21T04:55:34.597 に答える
1

タスクが終了したときに通知するために、タイムアウト値を指定してManualResetEventを待機します。通知される前にタイムアウトした場合は、非同期操作が完了していないことがわかります。

private ManualResetEvent receiveDone = new ManualResetEvent(false);

receiveDone.Reset();
socket.BeginReceive(...);
if(!receiveDone.WaitOne(new TimeSpan(0, 0, 0, 30))) //wait for 30 sec.
    throw new SocketException((int)SocketError.TimedOut);

BeginReceive コールバック内で、使用

private void ReceiveCallBack(IAsyncResult ar)
{
    /** Use ar to check if receive is correct and complete */
    receiveDone.Set();
}
于 2012-07-12T06:54:06.183 に答える