void
void

Reputation: 1377

.net sockets ObjectDisposed exception

I am using async sockets in my project.

When i calling Disconnect method in my class NotifyConnection ObjecDispoded exception arises. I realize that that happen becaouse socket.Close() method calls Dispose inside.

Have anyone idea how close socket in this situation ?

    public void Disconnect()
    {
        try
        {
            lock (_syncRoot)
            {                    
                _clientSocket.Shutdown(SocketShutdown.Both);
                _clientSocket.Close();
            }
        }
        catch (SocketException ex)
        {
            OnSocketExeceptionThrowed(new EventArgs<SocketException>(ex));
            NotificationAgentEm.LogExceptionToConsole(ex);
        }

    }

I expcect what EndReceive not called because socket.ShutDown closes socket receiving data..but EndReceive called after socket.ShutDown;socket.Close.

End exception throwed because socket not exist at this moment.

   private void OnReceiveData(IAsyncResult ar)
    {
        try
        {
            TransferStateObject state = null;
            lock(_syncRoot)
            {
                string message;
                state = (TransferStateObject)ar.AsyncState;
                // in this place exception throwed . client socket not exist becaouse it destroyed in disconnect method
                int bytesRead = _clientSocket.EndReceive(ar);

keleton of how i using async sockets.

   public void Connect(string host, int port)
    {
        if (host == null)
            throw new NullReferenceException();            
        try
        {
            _clientSocket = new Socket(AddressFamily.InterNetwork,
                                   SocketType.Stream, ProtocolType.Tcp);
            _clientSocket.Connect(host, port);
        }
        catch (Exception ex)
        {
            NotificationAgentEm.LogExceptionToConsole(ex);
            throw;
        }
    }
   public void Disconnect()
    {
        try
        {
            lock (_syncRoot)
            {                    
                _clientSocket.Shutdown(SocketShutdown.Both);
                _clientSocket.Close();
            }
        }
        catch (SocketException ex)
        {
            OnSocketExeceptionThrowed(new EventArgs<SocketException>(ex));
            NotificationAgentEm.LogExceptionToConsole(ex);
        }

    }
       public void StartListen()
    {
        if (_clientSocket == null)
        {
            throw new InvalidOperationException("No connection");
        }
        try
        {
            BeginReceive();
        }
        catch (SocketException ex)
        {              
            NotificationAgentEm.LogExceptionToConsole(ex);
            OnSocketExeceptionThrowed(new EventArgs<SocketException>(ex));
        }
    }  

  private void BeginReceive()
    {
        try
        {
            var receivedTranferObject = new TransferStateObject();
            _clientSocket.BeginReceive(
                receivedTranferObject.Buffer,
                0,
                TransferStateObject.BufferSize,
                0,
                new AsyncCallback(OnReceiveData),
                receivedTranferObject);
        }
        catch(SocketException ex)
        {
            OnSocketExeceptionThrowed(new EventArgs<SocketException>(ex));
            NotificationAgentEm.LogExceptionToConsole(ex);
        }
    }
  private void OnReceiveData(IAsyncResult ar)
    {
        try
        {
            TransferStateObject state = null;
            lock(_syncRoot)
            {
                string message;
                state = (TransferStateObject)ar.AsyncState;
                // in this place exception throwed . client socket not exist becaouse it    destroyed in disconnect method
                int bytesRead = _clientSocket.EndReceive(ar);
                 //bla bla bla
             }
         }

p.s sorry for my english

Upvotes: 0

Views: 368

Answers (1)

Mario The Spoon
Mario The Spoon

Reputation: 4869

Regardless of my comment above I would restructure the Disconnect method:

try
{
  lock (_syncRoot)
  {                    
      if ( null != _clientSocket )
      {
           _clientSocket.Shutdown(SocketShutdown.Both);
           _clientSocket.Close();
           _clientSocket = null;
       }
   }
}
catch (SocketException ex)
...

So you do not shutdown/ close the socket a second time around.

But again, to really help you we would need more details on the main workflow.

hth

PS: I do know about the penalty of having the if inside the lock, but I wanted to keep it simple,

Mario

EDIT: I added the function after the discussion in the comments section:

private void OnReceiveData(IAsyncResult ar)
{
  if ( null != _clientSocket )
  { 
     try
      {
        TransferStateObject state = null;
        lock(_syncRoot)
        {
          string message;
          state = (TransferStateObject)ar.AsyncState;
          int bytesRead = _clientSocket.EndReceive(ar);
          //bla bla bla
        }
      }
   }
  else
  {
    //socket has been closed/ is closing
   }
}

hth

Mario

Upvotes: 1

Related Questions