2013-06-04 7 views
5

I zostały przekazanie zamykania i przerywania kanałów w następujący sposób:Czy jest możliwe, aby kanał WCF powodował błąd po sprawdzeniu stanu (pojedynczy wątek)?

public async Task<MyDataContract> GetDataFromService() 
{ 
    IClientChannel channel = null; 
    try 
    { 
     IMyContract contract = factory.CreateChannel(address); 
     MyDataContract returnValue = await player.GetMyDataAsync(); 
     channel = (IClientChannel); 
     return returnValue; 
    } 
    catch (CommunicationException) 
    { 
     // ex handling code 
    } 
    finally 
    { 
     if (channel != null) 
     { 
      if (channel.State == CommunicationState.Faulted) 
      { 
       channel.Abort(); 
      } 
      else 
      { 
       channel.Close(); 
      } 
     } 
    } 
} 

przyjmować tylko pojedyncze nitki wykorzystuje kanał. Skąd wiemy, że kanał nie będzie miał błędów po sprawdzeniu stanu? Jeśli coś takiego miało się stać, kod spróbowałby Close() i Close() rzuciłby wyjątek w bloku finally. Wyjaśnienie, dlaczego jest to bezpieczne/niebezpieczne, a przykłady lepszej i bezpieczniejszej metody zostałyby docenione.

+0

Nie jestem pewien, czy rzut Zamknij, jeśli drugi koniec kanału nagle ulegnie uszkodzeniu? Umieść punkt przerwania tuż przed zamknięciem, zamknij usługę i sprawdź, czy zamknie się rzut Zamknij. – asawyer

+0

Dobra sugestia, chory, spróbuj, kiedy dostanę szansę później dzisiaj. Ale musiałbym przetestować, czy na prawie każdym stosie kanałów, który używam, aby być bezpiecznym, czy nie? – insipid

+0

W dużym stopniu korzystam z usług WCF w produkcji na żywo i nigdy nie widziałem żadnych błędów z klas obsługi usług. Zostały one nazwane 2 + milion razy w ciągu ostatnich 8 miesięcy. Wydaje się, że jest ok, ale twoje pytanie jest interesujące, nie myślałem o tym, więc nigdy nie próbowałem się dowiedzieć ... – asawyer

Odpowiedz

2

Tak, stan jest "migawką" bieżącego stanu, kiedy ją otrzymasz. W czasie między momentem, w którym uzyskujesz dostęp do CommunicationState i kiedy podejmujesz decyzję opartą na logice, stan może się łatwo zmienić. Lepszy wzór WCF to:

try 
{ 
    // Open connection 
    proxy.Open(); 

    // Do your work with the open connection here... 
} 
finally 
{ 
    try 
    { 
     proxy.Close(); 
    } 
    catch 
    { 
     // Close failed 
     proxy.Abort(); 
    } 
} 

W ten sposób nie można polegać na stanie w celu podejmowania decyzji. Próbujesz zrobić najbardziej prawdopodobną rzecz (zdrowe zamknięcie), a jeśli to się nie powiedzie (co nastąpi, gdy Stan Komunikacji zostanie zaatakowany), wywołasz Przerwij, aby zapewnić właściwe oczyszczenie.

Powiązane problemy