2013-06-04 88 views
5

我已被移交的關閉和中止信道的這種方式:檢查狀態(單線程)後,WCF通道是否可能發生故障?

public async Task<MyDataContract> GetDataFromService() 
{ 
    IClientChannel channel = null; 
    try 
    { 
     IMyContract contract = factory.CreateChannel(address); 
     MyDataContract returnValue = await player.GetMyDataAsync(); 
     channel = (IClientChannel); 
     return returnValue; 
    } 
    catch (CommunicationException) 
    { 
     // ex handling code 
    } 
    finally 
    { 
     if (channel != null) 
     { 
      if (channel.State == CommunicationState.Faulted) 
      { 
       channel.Abort(); 
      } 
      else 
      { 
       channel.Close(); 
      } 
     } 
    } 
} 

假設只有一個線程所使用的信道。我們如何知道在查看狀態後頻道不會錯誤?如果發生這樣的事情,代碼將嘗試Close()和Close()將在finally塊中引發異常。爲什麼這是安全/不安全的解釋,以及更好,更安全的方式的例子,將不勝感激。

+0

我不太確定,如果通道的另一端突然出現故障,將會關閉嗎?在關閉之前放置一個斷點,關閉服務,看看Close是否會拋出。 – asawyer

+0

好的建議,生病嘗試,當我今天晚些時候有機會。但是我必須測試一下,我所使用的每個通道堆棧都不是我的嗎? – insipid

+0

我在現場製作中大量使用WCF服務,並且從未看到服務處理類出現任何錯誤。他們在過去8個月中被稱爲2 + 100萬次。這似乎是好的,但你的問題很有趣,我沒有考慮它,所以我從來沒有試圖找出... – asawyer

回答

2

是的,當你得到它時,狀態是當前狀態的「快照」。在您訪問CommunicationState和基於此做出邏輯決策之間的時間內,狀態可以輕鬆更改。更好的WCF模式是:

try 
{ 
    // Open connection 
    proxy.Open(); 

    // Do your work with the open connection here... 
} 
finally 
{ 
    try 
    { 
     proxy.Close(); 
    } 
    catch 
    { 
     // Close failed 
     proxy.Abort(); 
    } 
} 

以這種方式,您不需要依賴狀態來做出決定。您嘗試做最可能的事情(健康的關閉),如果失敗(當CommunicationState出現故障時它會發生),您可以調用Abort來確保正確清理。