2012-02-16 72 views
4

我從UdpClient通過平時的異步回調接收數據:如何知道UdpClient是否已關閉/處置?

private void OnUdpData(IAsyncResult result) 
{ 
    byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint); 

    //Snip doing stuff with data 

    _udpReceive.BeginReceive(OnUdpData, null); 
} 

當我在主線程Close()的UdpClient,回調火災,因爲我所期望的,但在這一點_udpReceive已經佈置和我當我嘗試撥打時,請致電EndReceive()。我期待得到一個空的緩衝區。

什麼是正確的操作方法是什麼?有沒有的UdpClient一些成員,我可以嘗試使用它之前檢查,或將其包裝都在一個try{},趕上ObjectDisposedException的唯一途徑?這對於正常關閉來說似乎非常討厭。

回答

4

這完全是設計。你做了一些特殊的事情,即使你期望收到數據,你關閉了套接字。所以你會得到一個異常。 .NET框架總是確保異步調用已完成,並在調用EndXxx()時在回調中指示中止原因。好主意,可以讓你清理與回調相關的任何狀態。

你可以把它非特殊由等到轉讓完成後,停止調用BeginReceive()和然後關閉套接字。但是這並不總是實用的,或者有時你真的想早點結束。不是問題,只需捕獲ObjectDisposedException並退出即可。當然,考慮線路另一端的應用會發生什麼。之後它發送的任何內容都將落入小桶中,無法找到答案。

5

你可以這樣做來檢查它是否被處置。客戶端在UdpClient處置時設置爲空。

private void OnUdpData(IAsyncResult result) 
{ 
    if (_udpReceive.Client == null) 
     return; 
    byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint); 

    //Snip doing stuff with data 

    if (_udpReceive.Client == null) 
     return; 
    _udpReceive.BeginReceive(OnUdpData, null); 
} 

雖然因爲您在一個單獨的線程中關閉它,所以最終會出現競爭條件。最好只捕獲ObjectDisposedException和SocketException。

private void OnUdpData(IAsyncResult result) 
{ 
    try 
    { 
     byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint); 

     //Snip doing stuff with data 

     _udpReceive.BeginReceive(OnUdpData, null); 
    } 
    catch (Exception e) 
    { 
     //You may also get a SocketException if you close it in a separate thread. 
     if (e is ObjectDisposedException || e is SocketException) 
     { 
      //Log it as a trace here 
      return; 
     } 
     //Wasn't an exception we were looking for so rethrow it. 
     throw; 
    } 
} 
+0

回調是否解除了調用'EndReceive'的責任之一?我的印象是,除了某些不綁定資源的類型'IAsyncResult'(例如'Control.BeginInvoke'的返回值)之外,總是應該*每次'BeginXX'後總是調用'EndXX'。請注意,所遇到的異常並不表示「EndReceive」操作失敗,而是「成功的」EndReceive調用中繼導致接收嘗試的異常的結果。 – supercat 2012-02-24 17:22:12

+0

是不是隻調用EndX來從BeginX獲取數據?那麼在這種情況下,返回是好的。 EndReceive將檢查相同的東西,並拋出一個處置異常。 – Will 2012-02-25 15:49:50

相關問題