2011-04-19 88 views
0

我在我的项目中使用异步套接字。.net套接字ObjectDisposed异常

当我在我的类NotifyConnection ObjecDispoded异常出现时调用Disconnect方法。 我意识到,这发生becaouse socket.Close()方法调用Dispose里面。

有没有人知道socket在这种情况下有多接近?

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

    } 

我expcect什么EndReceive不叫,因为socket.ShutDown关闭套接字接收data..but EndReceive socket.ShutDown后调用; 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对不起,我的英语无论我的评论上述我会重组Disconnect方法的

+1

您不必关闭连接,一旦它的处置据我所知。 – CodingBarfield 2011-04-19 08:20:30

+0

很难说出问题出在哪里,你需要给我们更多关于'主循环'的细节 – 2011-04-19 08:22:22

+0

如果你认为Disconnect在接收数据的同时被调用,那么检查你的程序逻辑。您也可以在Disconnect中设置一个断点,并查看来电的来源。 – 2011-04-19 08:34:25

回答

1

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

所以,你不关机/关闭套接字第二往返时间。

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

心连心

PS:我不知道有的处罚如果锁里面,但我想保持它的简单,

马里奥

编辑:我以后添加的功能在评论部分讨论:

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 
    } 
} 

心连心

马里奥

+0

我更新了问题。 locke里面的代码我放置,以防止在那一刻断开连接,然后套接字接收并计算一些信息 – void 2011-04-19 08:29:30

+0

重组不会帮助(现在空引用异常出现在EndReceive方法 – void 2011-04-19 08:35:01

+0

只有当您完成连接/关闭应用程序时才会出现此问题或者当你正在接收数据? – 2011-04-19 08:43:42