język C#: Współbieżność(wielowątkowość)

Zwykle aplikacje czy programy w komputerze lub telefonie wykonują więcej niż jedną operację to się nazywa współbieżność, omówimy sobie najpierw podstawy współbieżności czyli wątki i zadania a w następnej lekcji przejdziemy do asynchroniczności.

Najczęściej spotykane przykłady współbieżności:

  1. W aplikacjach  mobilnych, WPF, stronach internetowych zadania muszą być wykonywane współbieżnie razem z kodem odpowiedzialnym za obsługę interfejsu użytkownika żeby zachować responsywność.
  2. System operacyjny wykonuje niektóre zadania współbieżnie, np gdy masz włączony komputer masz zwykle włączony więcej niż jeden program, gdyby system operacyjny nie wykonywał tych zadań współbieżnie to moglibyśmy w jednej chwili mieć włączony tylko jeden program.
  3. W portalach lub sklepach internetowych gdy w jednej chwili korzysta z nich więcej niż jeden użytkownik, współbieżność pozwala w jednej chwili przetwarzać więcej niż jedno żądanie klienta.

 

Wątkowanie

Wątek to ścieżka wykonywania, która może być realizowana niezależnie od innych ścieżek np głównym wątkiem w jakimś programie jest np obliczanie jakiegoś wyrażenia więc jest on jednowątkowy, a gdyby np był wielowątkowy to wiele wątków mogłoby być uruchomionych w jednej chwili np obliczałby jakąś wartość a w tej samej chwili mógłby wykonywać  w tle co innego, jakoś metodę, której wynik wyświetlałby np po obliczeniu wartości.

W głównym wątku w metodzie „Main” tworzymy trzy inne wątki, metody, które wyświetlają znaki w konsoli i można zauważyć, że w tym samym czasie są wyświetlane znaki z metody „Main”, czyli nasz program jest wielowątkowy.

Można również zaczekać, aż wątek zakończy pracę, wtedy trzeba dopisać metodę Join()

Widać różnice, że wątki wykonują się teraz po kolei.

Można również uśpić wątek na jakiś czas, uśpijmy wątek y:

W tym przykładzie, od razu wykona się metoda WriteY(), następnie do wykonania następnych wątków musimy poczekać 3 sekundy, natomiast trzeba podać czas w milisekundach.

Natomiast z wątkami jest pewien problem spójrz na poniższy przykład:

W jednym momencie są wykonywane dwa wątki, które uruchamiają tą samą metodę, spowoduje to wyświetlenie dwa razy słowa „Done” w konsoli.

Jak można sprawdzić bezpieczeństwo wątków? Do tego używa się słowa kluczowego „lock”. Zabezpieczmy zatem nasze wątki w poniższym przykładzie.

Rozwiązanie zastosowane w powyższym przykładzie, gwarantuje, że w jednej chwili można nałożyć tylko jedną blokadę na wątek, czyli wyświetli się nam tylko raz słowo „Done”.

Czasem zachodzi potrzeba przekazania danych do wątku. W tym przypadku najłatwiej użyć wyrażenia lambda:

 

Zadania

Wątek to niskiego poziomu narzędzie przeznaczone to zapewnienia współbieżności i w związku z tym ma pewne ograniczenia.

  1. Można łatwo przekazać do niego dane, ale już nie jest łatwo otrzymać z niego wartość zwrotną.
  2. Nie można nakazać wątkowi wykonywania innego wątku po jego zakończeniu. Zamiast tego konieczne jest użycie metody Join() co oznacza zablokowanie wątku w tym czasie.

Bezpośrednie używanie wątków również pogarsza wydajność.

Rozwiązaniem wszystkich tych problemów jest Klasa Task.

 

Uruchomienie zadania

Zadania tworzy się w taki sposób:

Zapis ten jest odpowiednikiem wątków w takiej postaci:

 

Wait()

Wywołanie Wait() jest odpowiednikiem metody join() w wątkach:

 

Wartość zwrotna

W wątkach trudne do zrobienia w taskach trywialne:

 

Kontynuacje

Kontynuacje można by przetłumaczyć do zdania „po zakończeniu rób co innego”. Są dwa sposoby zdefiniowania kontynuacji dla zadania, pierwszy jest ważny bo jest wykorzystywany w funkcjach asynchronicznych o czym się dowiesz w następnej lekcji, poniżej przykład:

Drugi sposób na dodanie kontynuacji to wywołanie metody ContinueWith():

 

Task.Delay()

Metoda Task.Delay() to asynchroniczny odpowiednik Thread.Sleep():

Dobrneliśmy do końca, wiedza z tej lekcji będzie potrzebna do następnej, więc dobrze zrozum materiał w niej.

 
Jeśli ten wpis ci się przydał podziel się nim ze swoimi znajomymi :)

Post a comment

avatar
  Subscribe  
Notify about