2013-05-03 10 views
5

Co to jest najlepsza metoda usuwania/czyszczenia instancji serwera proxy usług sieciowych po użyciu synchronicznym?Utylizacja/czyszczenie serwerów proxy usług sieciowych

Czym różni się odpowiedź, jeśli klasa proxy pochodzi z SoapHttpClientProtocol versus ClientBase<T>?

Tło

próbuję dowiedzieć się, dlaczego jeden z moich usług WCF internetowych wydaje się czasami dostać się do stanu, w którym nie ma już reponds do obsługi połączeń. Zasadniczo wygląda na to, że się zawiesił i na razie nie mam żadnych twardych danych, aby dowiedzieć się, co się dzieje, kiedy to się pojawi.

Jedna rzecz, którą podejrzewam, może być problem, to fakt, że ta usługa WCF sama wykonuje wywołania usługi sieci Web do kilku innych usług. Te inne usługi nazywane są (synchronicznie) za pomocą serwerów proxy, które pochodzą z SoapHttpClientProtocol (wykonane za pomocą wsdl.exe) i w tym czasie te przypadki proxy są pozostawione być czyszczone przez finalizatora:

... 
var testProxy = new TestServiceProxy(); 
var repsonse = testProxy.CallTest("foo"); 

// process the reponse 
... 

Więc mam po prostu zapakować je w blok using(...) { ... }?

... 
using(var testProxy = new TestServiceProxy()) 
{ 
    var repsonse = testProxy.CallTest("foo"); 

    // process the reponse 
} 
... 

Co gdybym zmienić te klasy proxy się opierać na ClientBase<T> odtwarzając je za pomocą svcutil.exe? Na podstawie moich dotychczasowych badań wydaje się, że metoda klas wywodząca się z wywoła wewnętrznie metodę klasy Close() i ta metoda może z kolei powodować wyjątki. Więc zawijanie proxy na podstawie ClientBase<T> w Using() nie zawsze jest bezpieczne.

Więc powtórzyć pytanie (s):

  • Jak należy oczyścić mojego serwera proxy usługi internetowej po użyciu go, gdy pełnomocnikiem jest oparta na SoapHttpClientProtocol?
  • Jak należy wyczyścić mój serwer proxy usług sieciowych po użyciu go, gdy serwer proxy jest oparty na ClientBase<T>?

Odpowiedz

12

podstawie moich najlepszych starań, aby znaleźć odpowiedź na to pytanie, chciałbym powiedzieć, że dla SoapHttpClientProtocol proxy oparte (regularne .asmx Prokurenci usług internetowych) prawidłowe sposobem jest simly zawinąć go w using():

using(var testProxy = new TestAsmxServiceProxy()) 
{ 
    var response = testProxy.CallTest("foo"); 

    // process the reponse 
} 

Dla pełnomocników na podstawie ClientBase<T> (WCF prokurenci) odpowiedzią jest to, że nie powinno być zapakowane w using() oświadczeniu. Zamiast tego należy zastosować następujący wzór (msdn reference):

var client = new TestWcfServiceProxy(); 
try 
{ 
    var response = client.CallTest("foo"); 
    client.Close(); 

    // process the response 
} 
catch (CommunicationException e) 
{ 
    ... 
    client.Abort(); 
} 
catch (TimeoutException e) 
{ 
    ... 
    client.Abort(); 
} 
catch (Exception e) 
{ 
    ... 
    client.Abort(); 
    throw; 
} 
+0

Nie jestem pewien co do pierwszej części tego. 'Dispose' jest zaimplementowane przez' Component', ale 'Abort' jest zaimplementowane przez' WebClientProtocol'. Patrząc na kod, wydaje się, że 'Dispose' nie mógł wiedzieć o żądaniu. Wydaje się, że https://msdn.microsoft.com/en-us/library/ff647786.aspx to potwierdził (w punkcie "Przerywanie połączeń dla stron ASP.NET, w których upłynął limit czasu, zanim połączenie z usługami Web Service zostanie zakończone"). W przypadku WCF zobacz https://stackoverflow.com/questions/573872/what-is-the-best-workaround-for-wcf-client-using-block-issue – TrueWill

Powiązane problemy