70-503: Concurrency in WCF Applications

Ten artykuł pochodzi z serii przygotowań do egzaminu 70-503: Windows Communication Foundation.

Współbieżność (ang. concurrency) w serwisie WCF występuje, kiedy jednocześnie więcej niż jedno wywołanie ma miejsce. Celem serwisu WCF jest przetwarzanie przychodzących żądań. Kiedy żądanie przychodzi do serwisu, serwis rozdziela (ang. dispatch) komunikaty na własne wątki, które brane są z puli wątków. Z każdym żądaniem powiązany jest obiekt serwisu – instancja klasy, która implementuje interfejs serwisu. W WCF kwestia współbieżności zależy od tego, jak te obiekty są tworzone i dzielone pomiędzy pojedyncze żądania.

WCF przewiduje trzy możliwe tryby dzielenia obiektu serwisu:

  • Single – każdy wątek, który obsługuje żądanie może mieć dostęp do obiektu serwisu, ale tylko jeden w danym czasie, używanie trybu Single zmniejsza ilość problemów związanych z współbieżnością,
  • Reentrant – tylko jeden wątek może mieć dostęp do obiektu serwisu w danym czasie, jednak ma on możliwość opuszczenia obiektu i powrotu do niego w późniejszym czasie,
  • Multiple – obiekt serwisu obsługuje jednocześnie wiele żądań; jest to najtrudniejszy tryb do implementacji, ponieważ wymaga wielkiej staranności przy korzystaniu z zasobów dzielonych (ang. shared resources).

Tryb współbieżności jest ustawiany korzystając z atrybutu ServiceBehavior - ConcurrenczMode, na klasie, która implementuje serwis.

Tryb współbieżności Single

Ustawienie ConcurrencyMode na wartość ConcurrencyMode.Single gwarantuje najbardziej bezpieczne środowisko dla współbieżności.

   1: [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single)]
   2: public class ServiceImplementation : IServiceInterface
   3: {
   4:   // TODO: Implementacja...
   5: }

Przed rozpoczęciem przetwarzania żądania, na obiekt serwisu zakładana jest blokada, która zdejmowana jest dopiero po zakończeniu operacji. Jeżeli w tym czasie przyjdą kolejne żądania, zostaną one odłożone na kolejkę (FIFO – first-in, first-out) i czekają, kiedy obiekt serwisu będzie dostępny. Przetwarzanie pojedynczego żądania w danym czasie eliminuje problemy zarządzanie współbieżnością. Jedyną sytuacją, kiedy może pojawić się problem jest sytuacja, gdy obiekt serwisu wykonuje operacje wielowątkowe. Istnieje tu jednak pewien kompromis, którym zależy od trybu wystąpienia. Innymi słowy należy uwzględnić związek pomiędzy ConcurrencyMode a InstanceContextMode.

Przykład: Zakładamy, że mamy podaną gotową implementację serwisu. Jak możemy udekorować klasę, aby wyeliminować współbieżność, nie modyfikując niczego wewnątrz klasy?

   1: [ServiceBehavior()]
   2: public class ServiceImplementation : IServiceInterface
   3: {
   4:   private static int hitCounter;
   5:   public void Increment()
   6:   {
   7:     hitCounter++;
   8:   }
   9: }

Możemy ustawić ConcurrencyMode na Single a InstanceContextMode na PerSession lub Single. Wykorzystanie trybu współbieżności Single zapewnia, że tylko jedno żądanie może być przetwarzane w danej chwili. Połączenie ConcurrencyMode w trybie Single i InstanceContextMode w trybie Single daje gwarancję, że jest tworzona tylko jedna instancja serwisu. To połączenie jest wymagane w przypadku operacji ze statycznymi lub dzielonymi zmiennymi, aby były zabezpieczone na naruszenia współbieżności.

Tryb Single cechuje potencjalnie niska przepustowość spowodowana przesyłaniem przychodzących żądań przez jeden obiekt.

Tryb współbieżności Multiple

W przypadku serwisów, które wymagają większej przepustowości dostępny jest model wielowątkowy. Kiedy ConcurrencyMode jest ustawiony na Multiple, nie występuje już zakładanie blokady na obiekt serwisu przed obsłużeniem żądania, a obiekt serwisu może (w zależności od trybu wystąpienia) obsłużyć wiele żądań jednocześnie. Informacja o stanie serwisu i dzielonych zasobach musi być chroniona poprzez wykorzystanie standardowych technik synchronizacji, które oferuje .NET framework.

Tryb współbieżności Reentrant

Serwis po ustawienie trybu na Reentrant zachowuje się tak samo jak w przypadku trybu Single. Przed przetworzeniem żądania zakładana jest blokada na serwis i trzymana jest tak długo, jak długo trwają operacje. Różnica leży w tym, co może się wydarzyć podczas samego przetwarzania.

imagePodczas przetwarzania żądania przez serwis może wystąpić sytuacja, że serwis musi wykonać operację na innym serwisie. Inne żądania do serwisu muszą czekać na zakończenie aktualnie przetwarzanego przez serwis żądania, gdzie serwis czeka na zakończenie wywołania, które sam rozpoczął. Problem ten ilustruje zamieszczony rysunek.

Co się teraz stanie, jeżeli zewnętrzny serwis wywoła żądanie na naszym serwisie WCF? Żądanie zostanie dodane do kolejki, obiekt serwisu nie zostanie odblokowany, wystąpi zakleszczenie! (WCF jest w stanie poradzić sobie z tym przez unieważnienie żądanie po pewnym czasie – timeout, lub rzucenie wyjątku InvalidOperationException). Tryb Reentrant rozwiązuje ten problem.

Różnica między trybem Single a Reentrant jest taka, że w tym drugim trybie, kiedy obiekt serwisu wykonuje własne żądanie zdejmowana jest blokada. Pozwala to na obsłużenie innych żądań. Kiedy odpowiedz na żądanie serwisu nadejdzie, zostanie dodana do kolejki razem z innymi żądaniami. Kiedy zacznie się jego przetwarzanie, założy blokadę na obiekt serwisu i dokończy swoje zadanie.

Chociaż konfiguracja serwisu do działania w trybie reentrant jest prosta, programista musi musi liczyć się z dużą odpowiedzialnością wiążącą się z tym rozwiązaniem. Zakleszczenia są problemem, jednak nie jedynym. Programista musi zapewnić, że kiedy serwis wykonuje żądanie, stan serwisu musi pozostać spójny – serwis nie powinien oddziaływać ze swoimi własnymi polami (publicznymi, czy prywatnymi, należącymi do instancji, czy statycznymi) w taki sposób, aby jakikolwiek obiekt pozostał w nieakceptowanym stanie. Przykładowo, jeżeli budujemy strukturę drzewiastą, nie możemy dopuścić do tego, aby korzeń drzewa nie był zdefiniowany.

W następnej, ostatniej już lekcji, zapoznamy się z synchronizacją.

Tagi: , , , , ,

Comments (1) -

Sławek Pełka
Sławek Pełka Poland
5/25/2010 10:33:49 AM Permalink

Ciekawy artykuł. Mimo, że z przygotowań do certyfikatu ;-)
Mam jedno ale - tłumaczenie na język polski mogłoby by być ciut staranniej dopracowane.

Pozdrawiam.

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


Eastgroup.pl na facebooku