2011-02-19 31 views
5

有StackOverflow上關於關閉WCF連接的幾個問題,但排名最高的答案是指這個博客:WCF的「使用」語句中的異常未正確關閉連接。如何關閉有故障的WCF客戶端連接或具有異常的連接?

http://marcgravell.blogspot.com/2008/11/dontdontuse-using.html

我有,當我在服務器上設置一個斷點,並讓這種技術的一個問題客戶端掛起超過一分鐘。 (我故意創建超時例外)

問題是客戶端似乎「掛起」,直到服務器完成處理。我的猜測是,一切都在後例外清理。

至於它出現在客戶端的retry()邏輯會再繼續,反覆重新提交查詢到的服務器在那裏我可以看到服務器端的調試器排隊的請求,然後執行每個TimeOutException排隊請求併發。我的代碼不希望WCF以這種方式行事,可能是我看到的數據損壞問題的原因。

有些東西並不完全與此解決方案加起來。

什麼是處理在WCF代理故障和異常 的包羅萬象的現代生活方式 ?

回答

7

更新

誠然,這是一個有點平凡的代碼來寫。 I currently prefer this linked answer,並且在該代碼中沒有看到任何可能導致問題的「黑客」。


這是微軟處理WCF客戶推薦的方式調用:

更多細節請參見:Expected Exceptions

try 
{ 
    ... 
    double result = client.Add(value1, value2); 
    ... 
    client.Close(); 
} 
catch (TimeoutException exception) 
{ 
    Console.WriteLine("Got {0}", exception.GetType()); 
    client.Abort(); 
} 
catch (CommunicationException exception) 
{ 
    Console.WriteLine("Got {0}", exception.GetType()); 
    client.Abort(); 
} 

信息 因此,許多人似乎是在問這個問題微軟甚至創建了一個WCF專用示例來演示如何處理異常:

C:\ WF_WCF_Samples \ WCF \基本\客戶端\ ExpectedExceptions \ CS \客戶

下載樣本: C#VB

考慮到有這麼多的問題involving the using statement(heated?) Internal discussionsthreads在這個問題上,我不會浪費時間試圖成爲一名牛仔代碼,並找到更清晰的方式。我只是把它吸了起來,併爲我的服務器應用程序實現WCF客戶端這種冗長(但可信)的方式。

可選其他故障趕上

許多異常從CommunicationException派生,我不認爲大多數這些異常應該重試。我對MSDN上的每個異常都進行了努力,發現了一個可重試異常的簡短列表(除了上面的TimeOutException之外)。如果我錯過了應該重試的異常,請告訴我。

Exception mostRecentEx = null; 
for(int i=0; i<5; i++) // Attempt a maximum of 5 times 
{ 
    try 
    { 
     ... 
     double result = client.Add(value1, value2); 
     ... 
     client.Close(); 
    } 

    // The following is typically thrown on the client when a channel is terminated due to the server closing the connection. 
    catch (ChannelTerminatedException cte) 
    { 

     mostRecentEx = cte; 
     secureSecretService.Abort(); 
     // delay (backoff) and retry 
     Thread.Sleep(1000 * (i + 1)); 
    } 

    // The following is thrown when a remote endpoint could not be found or reached. The endpoint may not be found or 
    // reachable because the remote endpoint is down, the remote endpoint is unreachable, or because the remote network is unreachable. 
    catch (EndpointNotFoundException enfe) 
    { 

     mostRecentEx = enfe; 
    secureSecretService.Abort(); 
     // delay (backoff) and retry 
     Thread.Sleep(1000 * (i + 1)); 
    } 

    // The following exception that is thrown when a server is too busy to accept a message. 
    catch (ServerTooBusyException stbe) 
    { 
     mostRecentEx = stbe; 
     secureSecretService.Abort(); 

     // delay (backoff) and retry 
     Thread.Sleep(1000 * (i + 1)); 
    } 

    catch(Exception ex) 
    { 
     throw ex; // rethrow any other exception not defined here 
    } 
} 
if (mostRecentEx != null) 
{ 
    throw new Exception("WCF call failed after 5 retries.", mostRecentEx); 
} 
3

Closing and Disposing a WCF Service

由於該職位暗示,你關閉時沒有異常,當有錯誤,你中止。 Dispose,因此Using不應與WCF一起使用。

+1

基於這個問題中的鏈接,我確信在我看來,WCF的東西不應該實現IDisposable,而應該有一個完全不同的清理體系結構。 – NotMe 2011-02-19 03:46:51

相關問題