2009-08-06 15 views
14

Mam aplikację kliencką, która próbuje co 10 sekund, aby wysłać wiadomość przez usługę WWW WCF. Ta aplikacja kliencka będzie znajdować się na komputerze znajdującym się na pokładzie statku, który, jak wiemy, będzie miał nierówną łączność internetową. Chciałbym, aby aplikacja próbowała wysyłać dane za pośrednictwem usługi, a jeśli nie, aby umieścić w kolejce wiadomości, dopóki nie wyśle ​​ich za pośrednictwem usługi.Odzyskiwanie z wyjątku wyjątku CommunicationObjectFaultedException w WCF

Aby przetestować tę konfigurację, uruchamiam aplikację kliencką i usługę internetową (obie na moim komputerze lokalnym) i wszystko działa poprawnie. Próbuję symulować złe połączenie internetowe, zabijając usługę internetową i restartując ją. Jak tylko zabiję usługę, zacznę uzyskiwać komunikat CommunicationObjectFaultedExceptions - co jest oczekiwane. Ale po ponownym uruchomieniu usługi nadal otrzymuję te wyjątki.

Jestem prawie pewien, że jest coś, czego nie rozumiem w paradygmacie usługi sieciowej, ale nie wiem, co to jest. Czy ktokolwiek może zaoferować porady dotyczące tego, czy konfiguracja jest możliwa, a jeśli tak, jak rozwiązać ten problem (np. Ponownie ustanowić kanał komunikacji z usługą sieciową)?

Dzięki!

Klay

Odpowiedz

33

proxy obsługa klienta nie mogą być ponownie wykorzystane po ich nic zarzucić. Musisz wyrzucić stary i odtworzyć nowy.

Należy również upewnić się, że serwer proxy klienta został poprawnie zamknięty. Możliwe jest, że serwer proxy usługi WCF wyrzuci wyjątek przy zamknięciu, a jeśli tak się stanie, połączenie nie zostanie zamknięte, więc musisz przerwać. Użyj wzorca "try {Zamknij}/catch {Abort}". Pamiętaj również, że metoda dispose wywołuje close (a tym samym może rzucić wyjątek z dispose), więc nie możesz po prostu użyć użycia, jak w zwykłych klasach jednorazowych.

Na przykład:

try 
{ 
    if (yourServiceProxy != null) 
    { 
     if (yourServiceProxy.State != CommunicationState.Faulted) 
     { 
      yourServiceProxy.Close(); 
     } 
     else 
     { 
      yourServiceProxy.Abort(); 
     } 
    } 
} 
catch (CommunicationException) 
{ 
    // Communication exceptions are normal when 
    // closing the connection. 
    yourServiceProxy.Abort(); 
} 
catch (TimeoutException) 
{ 
    // Timeout exceptions are normal when closing 
    // the connection. 
    yourServiceProxy.Abort(); 
} 
catch (Exception) 
{ 
    // Any other exception and you should 
    // abort the connection and rethrow to 
    // allow the exception to bubble upwards. 
    yourServiceProxy.Abort(); 
    throw; 
} 
finally 
{ 
    // This is just to stop you from trying to 
    // close it again (with the null check at the start). 
    // This may not be necessary depending on 
    // your architecture. 
    yourServiceProxy = null; 
} 

Jest blogu artykuł o tym here

+0

+10 gdybym mógł - wow, to zachowanie jest całkowicie pod radar, nigdy nie pracował, co się dzieje gdybym nie natknął się na tę odpowiedź. –

+0

Bravo! Zaimplementowałem wersję tego jako metodę rozszerzenia: TryDispose na klasie proxy do użytku przez innych. –

+0

@ Moby's Stunt Double - czy jesteś w stanie udostępnić swój kod? – RichardHowells

Powiązane problemy