支持异步操作并遵守超时的.NET TcpClient/NetworkStream实现

5

根据问题数、论坛帖子等数量来看,BCL中的TcpClient/NetworkStream实现似乎缺乏良好的取消IO操作的支持。随着.NET 4.5中异步方法的增加,这种缺乏取消(或良好的超时支持)会使事情变得更加令人沮丧,因为在执行IO过程中,拒绝监视其CancellationToken的任务被取消变得更加复杂(几乎不可能)。

我见过许多实现方式,它们会启动额外的线程来监视网络操作,并在事情似乎出错时关闭底层流。在我们试图通过使用异步操作来节省这些资源的世界中,这感觉非常不好。

有没有人可以指导我如何有效地取消/超时网络IO操作,或者提供一个真正有效的强大的第三方实现?

1个回答

4
取消IO操作并不是一件容易的事情。从Vista开始,我们有了CancelIO功能,但这是一个相当新的东西,驱动程序需要支持它。
实际上,最好的方法是关闭套接字以取消所有操作。或者,您可以在任务周围实现一个包装函数,该函数在CancellationToken被设置时提供即时完成。IO操作仍将继续,但其结果将被丢弃。
这里有一个关于此问题的详细讨论:http://social.msdn.microsoft.com/Forums/da-DK/async/thread/54632b19-0e9c-4078-aa59-c4389e75b187

我认为CancelIo/CancelIoEx是操作系统级别的函数,而不是依赖于驱动程序来实现/支持它们的函数? - Andrew
它们是调用内核的Win32 API,内核通过驱动程序进行调用。如果您取消了一个大的读取操作,驱动程序需要通过告诉磁盘停止来进行协作。CancelIO具有物理效果。 - usr
2
谢谢你推荐这个方向。我原本以为CancelIo/CancelIoEx是操作系统级别的,不需要驱动程序级别的支持。在进一步研究后,我发现了这篇文章(之前不知道怎么错过了),它讨论了取消异步IO的挑战。看起来基于文件的IO正在进行改进,但网络IO并没有。http://social.msdn.microsoft.com/Forums/da-DK/async/thread/54632b19-0e9c-4078-aa59-c4389e75b187 - Andrew
2
这个链接很重要,所以我把它放到了我的回答中。 - usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接