2011-04-19 71 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