我正在使用NetworkStream& TcpClient使用BeginRead异步接收数据。我需要对此操作应用超时,以便在指定的时间后读取将被中止。
据我所知,NetworkStream或TcpClient不支持 - 有一个ReceiveTimeout属性,但这似乎只适用于同步等效 - 'Read'。
即使是底层的Socket类似乎也不支持其BeginReceive方法中的超时。
我已经搜索了这个问题,我看到的唯一建议的解决方案是设置另一个后台线程,如果在超时时间内没有完成,则取消操作。这看起来像是一个可怕的黑客。当然有更好的方法吗?
答案 0 :(得分:2)
这是唯一的方法,因为当您使用异步操作时,启动该操作的线程将执行其他操作。同步版本可以使用超时,因为执行线程被阻塞,直到Read操作完成。
但是,如果必须使用后台线程来取消操作,那么继续使用异步Begin / End方法就没有多大意义了。如果要分离后台线程,只需从后台线程执行同步读取操作,然后就可以使用ReceiveTimeout。
答案 1 :(得分: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();
}