Reputation: 120518
After calling Socket.Shutdown, Socket.Close and Socket.Disconnect, it appears that Socket.ReceiveAsync does not abort. Attempts to reuse the SocketAsycEventArgs object used in the ReceiveAsync call (suggested in the documentation as best practice) result in the error:
An asynchronous socket operation is already in progress using this SocketAsyncEventArgs instance
What do I have to do to get ReceiveAsync to release its grip on this SocketAsyncEventArgs instance?
Edit:I have worked around this by flagging a pending receive and not doing any cleanup until the receive comes in (i.e Completed is dispatched). Doesn't feel too good though. Can't it just be aborted, like the WebRequest API?
Upvotes: 14
Views: 8369
Reputation: 9
Most likely cause is when reusing SocketAsyncEventArgs that you are calling:
SAE.Completed += new EventHandler(SocketEventArg_Completed);
Doing so will cause your callback to be called multiple times!!!
Be sure to only set Completed handler once.
Upvotes: 0
Reputation: 46052
There does not appear to be a way to abort the asynchronous receive.
When the socket is closed, this forces the receive to complete, and the SocketError property of the SocketAsyncEventArgs parameter to your callback method will have a value of SocketError.OperationAborted
. When this condition is encountered, you can return the SocketAsyncEventArgs object to the reusable pool.
This is demonstrated in the example shown here. Specifically, look at the ProcessReceive() method, which calls the CloseClientSocket() method when e.BytesTransferred == 0
or e.SocketError != SocketError.Success
. The CloseClientSocket() method is where the SocketAsyncEventArgs object is returned to the pool.
Upvotes: 7