2011-07-18 11 views
8

Zawijam cały kod wywołujący wywołania WCF w ramach instrukcji using na myśl, że obiekt zostanie poprawnie usunięty. Kiedy szukam wyjątku "Usługa HTTP działająca w ... jest zbyt zajęta", stwierdziłem, że ten link http://msdn.microsoft.com/en-us/library/aa355056.aspx nie powinien używać instrukcji using w typowych serwerach proxy. Czy to naprawdę prawda? Myślę, że dostałem dużą zmianę kodu (westchnienie). Czy ten problem występuje tylko w typowych serwerach proxy?Problemy z korzystaniem z instrukcji Statement i klienta WCF

Przykładowy kod:

private ServiceClient proxy; 

using(proxy = new ServiceClient("ConfigName", "http://serviceaddress//service.svc")){ 
    string result = proxy.Method(); 
} 
+0

Zobacz również:. http://stackoverflow.com/questions/573872/what-is-the- najlepszy-workaround-za-wcf-klient-używając-blok-problem, a także: http://stevesmithblog.com/blog/idisposable-and-wcf/ –

+0

Interesujące. Nie sądzę, będziesz mieć problemy, jeśli używasz wiązania, takie jak basichttpbinding i utworzyć wystąpienie na serwerze na połączenie. – BennyM

+0

@BennyM: prawdopodobnie pojawią się te same problemy, niezależnie od tego, jakiego rodzaju wiązania używasz ..... –

Odpowiedz

16

sedno problemu jest: w końcu bloku using (! Co generalnie jest to bardzo dobry pomysł, aby mieć), proxy WCF będą usuwane. Jednak podczas usuwania proxy WCF mogą wystąpić wyjątki - a te spowodują nieprawidłowe działanie aplikacji. Ponieważ odbywa się to niejawnie na końcu bloku using, nawet nie widać, gdzie występuje błąd.

Więc zazwyczaj Microsoft recommends a pattern something like this:

private ServiceClient proxy; 

try 
{ 
    proxy = new ServiceClient("ConfigName", "http://serviceaddress//service.svc"); 
    string result = proxy.Method(); 
    proxy.Close();  
} 
catch (CommunicationException e) 
{ 
    // possibly log error, possibly clean up 
    proxy.Abort(); 
} 
catch (TimeoutException e) 
{ 
    // possibly log error, possibly clean up 
    proxy.Abort(); 
} 
catch (Exception e) 
{ 
    // possibly log error, possibly clean up 
    proxy.Abort(); 
    throw; 
} 

Trzeba wywołać metodę proxy.Close() wyraźnie i być przygotowanym do obsługi wyjątków, które mogą wystąpić z tej rozmowy, zbyt.

+0

Chciałbym potwierdzić jedną rzecz, jeśli Close() wyrzuca wyjątki, to połączenia są otwarte, więc po pewnym okresie usługa nie może obsłużyć nowych żądań rgt? – VJAI

+0

@ Mark: chyba że wywołasz 'proxy.Abort()' po tym, jak zdarzył się wyjątek - tak, to proxy może pozostawać w pobliżu ..... –

+0

, ale czy ta sama sytuacja nie dotyczy wszystkich obiektów implementujących Idisposable? – Stacker

2

Zawiń operację proxy i wywołanie instancji w klasie implementującej IDisposable. Podczas usuwania sprawdź właściwości stanu serwera proxy i uporządkuj kanał przed zamknięciem.

public void Dispose() 
{ 
    if (this.MyProxy != null && this.MyProxy.State == CommunicationState.Faulted) 
    { 
     this.MyProxy.Abort(); 
     this.MyProxy.Close(); 
     this.MyProxy = null; 
    } 
    // ...more tidyup conditions here 
} 
1

podoba mi się podejście z komentarzem „Eric” na tym blogu (który jest podobny do innego artykułu: http://redcango.blogspot.com/2009/11/using-using-statement-with-wcf-proxy.htm):

„Osobiście lubię stworzyć własną klasę częściową dla klienta . i zastąpić metodę Dispose() To pozwala mi korzystać z „używając” blok jak normalnie

public partial class SomeWCFServiceClient : IDisposable 
{ 
    void IDisposable.Dispose() 
    { 
    if (this.State == CommunicationState.Faulted) 
    { 
    this.Abort(); 
    } 
    else 
    { 
    this.Close(); 
    } 
    } 
} 
Powiązane problemy