2009-09-09 19 views
24

Jesteśmy przy użyciu usługi WCFZamknięcie połączenia WCF

po stronie klienta planujemy wyraźnie zamknąć połączenie Wydaje istnieje więcej niż jeden sposób zamykania

sample1: W końcu bloku konsumpcja usług WCF używać

if (client.State == CommunicationState.Faulted) 
{ 
    client.Abort(); 
} 
client.Close(); 

Ponieważ jeśli usługa jest w stanie błędu nie będzie mógł zadzwonić close()

Probka2:

using(ClientProxy proxy = new ClientProxy()) 
{ 
    //call your service methods 
} 

w sample2 nie jestem pewien, co się stanie, jeśli usługa jest w stanie błędu, będzie rzucać błąd zamykając połączenie?

+0

@ Balaji- spojrzeć na ten post- http://stackoverflow.com/questions/573872/what-is-the-best-workaround- for-the-wcf-client-using-block-issue. To jest bardzo pomocne – RichardOD

Odpowiedz

16

Druga próbka za pomocą bloku "using" jest niepoprawna. Blok użycia zapewnia wywołanie metody Dispose na obiekcie proxy. Metoda Dispose z kolei wywołuje metodę Close, która będzie (próbowała) połączyć się z usługą, która wyrzuci wyjątek, gdy stan komunikacji jest uszkodzony. Więc twoje uczucia/przeczucie są absolutnie słuszne. Byłoby miło, gdyby pełnomocnik utylizować metodą stosowaną kod z pierwszej próby, ale to nie tak nie korzystają z wykorzystaniem bloku :)

34

masz wszystkie potrzebne informacje pod ręką - uzyskany Best Practice w użyciu i odpowiednio blisko/przerwać wszystkie serwery proxy klienta WCF będzie:

YourClientProxy clientProxy = new YourClientProxy(); 

try 
{ 
    .. use your service 
    clientProxy.Close(); 
} 
catch(FaultException) 
{ 
    clientProxy.Abort(); 
} 
catch(CommunicationException) 
{ 
    clientProxy.Abort(); 
} 
catch (TimeoutException) 
{ 
    clientProxy.Abort(); 
} 

Złapanie wyjątku FaultException obsługuje wszystkie przypadki, gdy usługa jest odpowiedzialna za stan błędu (a tym samym kanał znajduje się w stanie błędu), a wyjątek CommunicationException obsłuży wszystkie inne wyjątki związane z komunikacją, takie jak upuszczenie połączenia sieciowego itp.

Metoda z blokiem using() nie będzie działać, ponieważ jeśli wyjątek wystąpi na końcu bloku, gdy metoda Dispose() wywoła metodę Close() na proxy klienta, nie ma możliwości łapanie i posługiwanie się tym.

+0

Dziękuję wszystkim za odpowiedź. Żałuję, że nie było pewnych ustawień w pliku web.config, aby zadbać o zamknięcie połączenia! – Balaji

+1

FaultException jest wyjątkiem CommunicationException, więc z technicznego punktu widzenia nie potrzebujesz obu klauzul catch (chyba że planujesz inaczej obsługiwać te dwa przypadki). – bobbymcr

+0

FaultException jest potomkiem wyjątku CommunicationException i masz rację - obsługa wyjątku CommunicationException byłaby dobra, o ile nie musisz w jakiś sposób robić różnych rzeczy w dwóch różnych przypadkach. Domyślam się, że to mój zwyczaj wymieniać najczęściej występujące typy wyjątków osobno, nawet jeśli nie zrobię nic specjalnego w żadnym z nich ... –

4

W Juval Lowy wspaniałe Programming WCF book on poleca:

try 
{ 
    ClientProxy clientProxy = new ClientProxy(); 
    clientProxy.SomeMethod(); 
    clientProxy.Close(); 
} 
catch 
{ 
    proxy.Abort(); 
} 
+2

Ha .. Widziałem ten kod w książce, ale myślę, że to się nie kompiluje. Usługa musi zostać zadeklarowana poza blokiem try, aby uzyskać dostęp do bloku catch ... a następnie prawdopodobnie chcesz umieścić wokół niego zerową kontrolę. – foson

+0

@ Foson - czy wiesz, na której stronie był? Masz rację co do powyższego kodu. Mam książkę, ale przeczytałem ją już jakiś czas temu. – RichardOD