5

Based on the number of questions, forum posts, etc, it appears that the TcpClient/NetworkStream implementation in the BCL lacks decent support for cancelling IO operations. With the addition of Async methods in .NET 4.5, this lack of cancellation (or decent timeout support) makes things even more frustrating since it becomes even more complicated (nigh on impossible) to cancel a task that refuses to monitor its CancellationToken while performing IO.

I have seen many implementations that spin up additional threads to monitor the network operation and close the underlying stream if things seem to be going wrong. This feels very dirty in a world where we're trying to conserve these resources by using async operations.

Can anyone point me in the direction of guidance as to dealing with efficiently cancelling/timing out network IO operations or towards a robust 3rd party implementation that actually works?

Andrew
  • 2,605
  • 3
  • 23
  • 34

1 Answers1

4

Cancelling IO is not trivial. Starting with Vista we have the CancelIO capability, but that is a fairly new thing and drivers need to support it.

Practically speaking, the best you can do is close the socket to cancel everything. Alternatively, you can implement a wrapper function around a task which provides instant completion when the CancellationToken becomes set. The IO operation would still continue but its result would be discarded.

Here is a thorough discussion about the issue: http://social.msdn.microsoft.com/Forums/da-DK/async/thread/54632b19-0e9c-4078-aa59-c4389e75b187

usr
  • 168,620
  • 35
  • 240
  • 369
  • I thought CancelIo/CancelIoEx were OS-level functions, rather than ones relying on drivers to implement/support them? – Andrew Jun 07 '12 at 11:06
  • They are Win32 APIs which call to the kernes which calls through to the driver. If you cancel a big read, the driver needs to cooperate by telling the disk to stop. CancelIO has physical effects. – usr Jun 07 '12 at 11:36
  • 2
    Thanks for pushing me in this direction. I figured CancelIo/CancelIoEx were OS-level and did not require driver-level support. Having done a bit more research around this, I came across this post (have no idea how I missed it before) which discusses the challenges of cancelling async IO. It appears that file-based IO is in line to get an overhaul but networking is not. http://social.msdn.microsoft.com/Forums/da-DK/async/thread/54632b19-0e9c-4078-aa59-c4389e75b187 – Andrew Jun 07 '12 at 16:14
  • 2
    This link is important, so I pulled it into my answer. – usr Jun 07 '12 at 16:18