在用戶端正確的關閉WCF串連! zt

來源:互聯網
上載者:User

在用戶端正確的關閉WCF串連!

如果你直接將用戶端調用Close關閉,或者使用using語句,那你將是個悲劇,這點相信使用WCF的同志都知道的,因為ClientBase類的Close()方法被調用後,實際上是關閉了一個網路會話,並且會拋出異常!CommunicationException和TimeoutException!

這似乎違反常理,但確實發生了。因為一般來說Close函數都不會拋出異常。這個問題的解決辦法是使用Try-Catch語句包含Close()方法,然後再異常處理中使用Abort函數釋放資源!

同樣,ClientBase類的IDisposable介面的實現函數Dispose方法中會調用Close函數,使用Reflector查看ClientBase<TChannel> 的代碼便知

所以你使用using語句同樣不能正確關閉WCF串連!而我們使用using語句就是為了不管發生什麼情況,只要離開範圍之後,就會釋放相關資源。而WCF的ClientBase類設計很明顯違反了這一觀念!簡直是坑爹啊!

解決這一問題網上以後很多方案,首先說說微軟的,也許是微軟也意識到這一點,所以微軟在提供的WCF樣本程式中特意包含了一個叫做UsingUsing的樣本,名字聽起來有點怪

主要解決的方法是如下的代碼

 1 // This method shows the correct way to clean up a client, including catching the 2         // approprate Exceptions. 3         static void DemonstrateCleanupWithExceptions() 4         { 5             // Create a client 6             CalculatorClient client = new CalculatorClient(); 7             try 8             { 9                 // Demonstrate a successful client call.10                 Console.WriteLine("Calling client.Add(0.0, 0.0);");11                 double addValue = client.Add(0.0, 0.0);12                 Console.WriteLine("        client.Add(0.0, 0.0); returned {0}", addValue);13 14                 // Demonstrate a failed client call.15                 Console.WriteLine("Calling client.Divide(0.0, 0.0);");16                 double divideValue = client.Divide(0.0, 0.0);17                 Console.WriteLine("        client.Divide(0.0, 0.0); returned {0}", divideValue);18 19                 // Do a clean shutdown if everything works.  In this sample we do not end up20                 // here, but correct code should Close the client if everything was successful.21                 Console.WriteLine("Closing the client");22                 client.Close();23             }24             catch (CommunicationException e)25             {26                 // Because the server suffered an internal server error, it rudely terminated27                 // our connection, so we get a CommunicationException.28                 Console.WriteLine("Got {0} from Divide.", e.GetType());29                 client.Abort();30             }31             catch (TimeoutException e)32             {33                 // In this sample we do not end up here, but correct code should catch34                 // TimeoutException when calling a client.35                 Console.WriteLine("Got {0} from Divide.", e.GetType());36                 client.Abort();37             }38             catch (Exception e)39             {40                 // In this sample we do not end up here.  It is best practice to clean up the41                 // client if some unexpected Exception occurs.42                 Console.WriteLine("Got unexpected {0} from Divide, rethrowing.", e.GetType());43                 client.Abort();44                 throw;45             }46         }

其實就是使用try-catch語句捕獲關閉時的異常!試想要是每次都這樣調用WCF服務將會是多麼痛苦的一件事情!網上也有人使用Linq的Expression來解決這一問題

於是我借用函數式編程的思想,設計了一個使用lambda運算式來解決這一問題的方案!

關鍵的函數很簡單,一看便知道是我是怎樣設計的!

 1 public static class SvcClient 2     { 3         public static void Invoke<TClient>(Action<TClient> act) 4             where TClient : System.ServiceModel.ICommunicationObject, new() 5         { 6             TClient client = new TClient(); 7             try 8             { 9                 act(client);10                 client.Close();11             }12             catch (System.ServiceModel.CommunicationException)13             {14                 client.Abort();15             }16             catch (TimeoutException)17             {18                 client.Abort();19             }20             catch (Exception)21             {22                 client.Abort();23                 throw;24             }25         }26     }

實際上這一設計的思想就是:將所有調用WCF服務的所有代碼做為一個函數傳入進來,然後我再內部使用try-catch語句包裹整個調用過程,這樣就巧妙的將處理關閉串連異常的代碼與實際調用過程分離開來!

函數的使用過程也比較方便

1 SvcClient.Invoke<Service1Client>(client =>2 {3   //在此處添加調用WCF的代碼4 });

代碼看起來比較簡潔優美,個人比較滿意,而且不用再擔心調用結束後不能正確關閉WCF串連,資源不能正確釋放的問題了!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.