Cancel NetworkStream.ReadAsync using TcpListener

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-28 11:36:26

No, NetworkStream does not support cancellation.

Unfortunately, the underlying Win32 APIs do not always support per-operation cancellation. Traditionally, you could cancel all I/O for a particular handle, but the method to cancel a single I/O operation is fairly recent. Most of the .NET BCL was written against the XP API (or older), which did not include CancelIoEx.

Stream compounds this issue by "faking" support for cancellation (and asynchronous I/O, too) even if the implementation doesn't support it. The "fake" support for cancellation just checks the token immediately and then starts a regular asynchronous read that cannot be cancelled. That's what you're seeing happen with NetworkStream.

With sockets (and most Win32 types), the traditional approach is to close the handle if you want to abort communications. This causes all current operations (both reads and writes) to fail. Technically this is a violation of BCL thread safety as documented, but it does work.

cts.Token.Register(() => client.Close());
...
catch (ObjectDisposedException)

If, on the other hand, you want to detect a half-open scenario (where your side is reading but the other side has lost its connection), then the best solution is to periodically send data. I describe this more on my blog.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!