tags:

views:

1078

answers:

5

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?

A: 

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.

Matt Davis
A: 

Here, I stopped using pool for SocketAsuncEventArgs becuase of the same exception.

I am getting the same exception eventhough instantiating a new SocketAsyncEventArgs object for each new connection.

Any idea what could be the reason?

same args being used for SendAsync,ReceiveAsync and/or AcceptAsync concurrently. The SocketAsyncEventArgs is only safe for reuse after its dispatches Completed. In some way, you must be reusing it before this happens.
spender
A: 

I use the TcpClient C#-class to create connections. If the connection will be aborted (someone takes out a plug connector or a bad network event happens etc.), how can I known it immediately (e.g. not by calls tcpClient.GetStream().Read/Write after the aborting only)? The basic socket of a TcpClient instance don't poll the connection probably, so it sends no events if the connection has been aborted. Or is there an event which the basic socket sends in that cases?

Best regards

Valerius, this would be better as a standalone question, as it is largely unrelated to the original post. TcpClient and Socket.xxxAsync are completely different APIs related only by the fact they deal with sockets
spender
A: 

Can you please provide some details about your workaround solution; how do you get the Completed event to be dispatched for the ReceiveAsync call without the other side closing the connection?

Bartol
A: 

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.

mberticus