How to abort socket's BeginReceive()?

Naturally, BeginReceive() will never end if there's no data. MSDN suggests that calling Close() would abort BeginReceive().

However, calling Close() on the socket also performs a Dispose() on it, as figured out in this great answer, and consequently EndReceive() would throw an exception because the object is already disposed (and it does!).

How should I proceed?


It seems like this is by (the very dumb) design. You must have this exception thrown and caught in your code.

MSDN looks silent about it indeed, but if you look at the documentation of another asynchronous socket method, BeginConnect(), here's what we find:

To cancel a pending call to the BeginConnect() method, close the Socket. When the Close() method is called while an asynchronous operation is in progress, the callback provided to the BeginConnect() method is called. A subsequent call to the EndConnect(IAsyncResult) method will throw an ObjectDisposedException to indicate that the operation has been cancelled.

If it is the proper way of doing for BeginConnect, it is probably so for BeginReceive as well. This is certainly a poor design on the part of Microsoft's async API, because making the user necessarily throw and catch exception as a part of a normal flow would annoy the debugger. You have really no way to "wait" until the operation is completed, because Close() is what completes it in the first place.


I am surprised no one recommended using SocketOptions.

Once the stack has the send or receive operation it is bound by the socket options of the socket.

Use a small send or receive timeout and use it before the operation so you don't care if it's changed during that same operation to something shorter or longer.

This will cause more context switching but will not require closing the socket under any protocol.

For example:

1) Set a small timeout

2) Perform operations

3) Set timeout larger

This is similar to using Blocking = false but with an automatic timeout that you specify.