在花费了比看起来更合理的时间来找到这个简单问题的答案之后,我想我会把我的结果留在这里,这样其他人就不必跳过我刚刚遵循的所有箍和错误的路径。
问题是,如果您使用 TcpClient ReadTimeout 属性并且您的读取操作实际上超时,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 的数十个站点中能够找到的最合适的解决方案。
我希望这个问题/评论可以节省我找到的时间。