使用 SocketAsyncEventArgs 的异步套接字操作超时
Timeout on asynchronous socket operation with SocketAsyncEventArgs
似乎无法在 .NET Socket
class 的 AcceptAsync()
方法上指定超时。它接受 SocketAsyncEventArgs
if (!socket.AcceptAsync(awaitable.EventArgs))
doasync();
else
dosync();
关于如何使此方法在特定时间范围后超时的任何建议?它似乎也适用于 ReceiveAsync()
方法。
Socket
本身有一些超时值,例如 ReceiveTimeout
,但文档表明它们不适用于异步方法。
ReceiveTimeout
并不像很多人想象的那么有用。除了只适用于同步Receive()
方法调用外,还有超时后socket不可用。没有办法让套接字上的接收操作超时,然后从同一个套接字恢复读取。
因此,无论操作类型如何,始终有效的备选方案被证明是可行的。具体来说:
- 为您想要的超时期限设置一个计时器
- 尝试操作
- 如果操作在超时前完成,则禁用计时器(或者如果完成一个操作后要立即进行另一次操作尝试,则重新启动计时器)
- 如果操作在超时前没有完成,关闭套接字。
关闭套接字将导致任何挂起的 I/O 操作以异常完成。当然,关闭套接字后,您将无法再次使用该套接字。但这就是底层套接字 API 的工作方式,所以这不是问题。
请注意,您的计时器和套接字操作正在加速。因此,重要的不仅是实现定时器,而且同步操作和定时器也是很重要的。例如。使用 volatile bool
标志来表示操作已成功完成,即使调用了定时器处理程序,也不应关闭套接字。
似乎无法在 .NET Socket
class 的 AcceptAsync()
方法上指定超时。它接受 SocketAsyncEventArgs
if (!socket.AcceptAsync(awaitable.EventArgs))
doasync();
else
dosync();
关于如何使此方法在特定时间范围后超时的任何建议?它似乎也适用于 ReceiveAsync()
方法。
Socket
本身有一些超时值,例如 ReceiveTimeout
,但文档表明它们不适用于异步方法。
ReceiveTimeout
并不像很多人想象的那么有用。除了只适用于同步Receive()
方法调用外,还有超时后socket不可用。没有办法让套接字上的接收操作超时,然后从同一个套接字恢复读取。
因此,无论操作类型如何,始终有效的备选方案被证明是可行的。具体来说:
- 为您想要的超时期限设置一个计时器
- 尝试操作
- 如果操作在超时前完成,则禁用计时器(或者如果完成一个操作后要立即进行另一次操作尝试,则重新启动计时器)
- 如果操作在超时前没有完成,关闭套接字。
关闭套接字将导致任何挂起的 I/O 操作以异常完成。当然,关闭套接字后,您将无法再次使用该套接字。但这就是底层套接字 API 的工作方式,所以这不是问题。
请注意,您的计时器和套接字操作正在加速。因此,重要的不仅是实现定时器,而且同步操作和定时器也是很重要的。例如。使用 volatile bool
标志来表示操作已成功完成,即使调用了定时器处理程序,也不应关闭套接字。