title: Async socket crashes when I close the socket
body: <p>The code shown below appears to almost work. If I create an instance of it and call "Connect" all works fine. When I call "Disconnect", sometimes everything is fine (mainly if I add a breakpoint and step through the function slowly). If I don't use a breakpoint the class(being hosted as a win forms app) seems to disappear (the form does) but visual studio still thinks it's running. In visual studio's output window I get "A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll". Can anyone spot what I'm doing wrong?</p>
  
  <pre><code>// State object for reading client data asynchronously
  public class StateObject
  {
      private Guid ID = Guid.NewGuid();
      // Client socket.
      public Socket workSocket = null;
      // Size of receive buffer.
      public const int BufferSize = 1024;
      // Receive buffer.
      public byte[] buffer = new byte[BufferSize];
  }
  
  public class NetworkComms : IBasePanel
  {
      private static ILog _log = LogManager.GetCurrentClassLogger();
  
      // ManualResetEvent instances signal completion.
      private static ManualResetEvent connectDone = new ManualResetEvent(false);
      private static ManualResetEvent sendDone = new ManualResetEvent(false);
      private static ManualResetEvent receiveDone = new ManualResetEvent(false);
  
      private static Socket _client = null;
      private static IPEndPoint _endpoint = null;
  
      public event ReceiveMessageEventHandler OnReceiveMessage; 
  
      public NetworkComms(string address, int port)
      {
          _endpoint = new IPEndPoint(GetIPAddress(address), port);
      }
  
      private IPAddress GetIPAddress(string address)
      {
          IPAddress ipAddress = null;
  
          if (IPAddress.TryParse(address, out ipAddress))
          {
              return ipAddress;
          }
          else
          {
              IPHostEntry ipHostInfo = Dns.GetHostEntry(address);
              return ipHostInfo.AddressList[ipHostInfo.AddressList.Count() - 1];
          }
      }
  
      private  void ConnectCallback(IAsyncResult ar)
      {
          // Retrieve the socket from the state object.
          Socket client = (Socket)ar.AsyncState;
  
          // Complete the connection.
          client.EndConnect(ar);
  
          _log.DebugFormat("Socket connected to {0}", client.RemoteEndPoint.ToString());
  
          // Signal that the connection has been made.
          connectDone.Set();
      }
  
      private void Receive()
      {
          // Create the state object.
          StateObject state = new StateObject();
          state.workSocket = _client;
  
          // Begin receiving the data from the remote device.
          _client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
      }
  
      private void ReceiveCallback(IAsyncResult ar)
      {
          // Retrieve the state object and the client socket 
          // from the asynchronous state object.
          StateObject state = (StateObject)ar.AsyncState;
          Socket client = state.workSocket;
  
          // Read data from the remote device.
          int bytesRead = client.EndReceive(ar);
  
          if (bytesRead &gt; 0)
          {
              // There might be more data, so store the data received so far.
              ReceivedNewMessage(Encoding.Default.GetString(state.buffer, 0, bytesRead));
  
              // Get the rest of the data.
              client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
          }
          else
          {
              // Signal that all bytes have been received.
              receiveDone.Set();
          }
      }
  
      private static void SendCallback(IAsyncResult ar)
      {
          // Retrieve the socket from the state object.
          Socket client = (Socket)ar.AsyncState;
  
          // Complete sending the data to the remote device.
          int bytesSent = client.EndSend(ar);
          _log.DebugFormat("Sent {0} bytes to server.", bytesSent);
  
          // Signal that all bytes have been sent.
          sendDone.Set();
      }
  
      public void SendMessage(byte[] message)
      {
          _client.BeginSend(message, 0, message.Length, 0, new AsyncCallback(SendCallback), _client);
          sendDone.WaitOne();
      }
  
      public void Connect()
      {
          _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          _client.BeginConnect(_endpoint, new AsyncCallback(ConnectCallback), _client);
          connectDone.WaitOne();
  
          Receive();
      }
  
      public void Disconnect()
      {
          try
          {
              _client.Shutdown(SocketShutdown.Both);
              _client.Close();
          }
          finally
          {
              _client = null;
  
              connectDone.Reset();
              sendDone.Reset();
              receiveDone.Reset();
          }
      }
  
      private void ReceivedNewMessage(string message)
      {
          if (this.OnReceiveMessage != null)
          {
              this.OnReceiveMessage(message);
          }
      }
  
      public bool IsConnected
      {
          get
          {
              if (_client == null) return false;
              return _client.Connected;
          }
      }
  }
  </code></pre>