.net sockets ObjectDisposed异常

时间:2011-04-19 08:18:50

标签: .net sockets

我在项目中使用异步套接字。

当我在我的类NotifyConnection中调用Disconnect方法时出现ObjecDispoded异常。 我意识到这发生了因为socket.Close()方法调用内部的Dispose。

有没有人知道在这种情况下插座有多紧密?

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

    }

我说明了EndReceive没有调用的内容,因为socket.ShutDown关闭了socket接收数据..但是在socket.ShutDown后调用了EndReceive; socket.Close。

结束异常抛出,因为此时套接字不存在。

   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我如何使用异步套接字。

   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抱歉我的英文

1 个答案:

答案 0 :(得分:1)

无论上面的评论如何,我都会重新构建Disconnect方法:

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

所以你不要再次关闭/关闭套接字。

但同样,为了真正帮助您,我们需要有关主要工作流程的更多详细信息。

HTH

PS:我确实知道在锁内有if的惩罚,但我想保持简单,

马里奥

编辑:我在评论部分讨论后添加了该功能:

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

马里奥