Wątkowanie w środowisku Xamarin.iOS

Środowisko uruchomieniowe platformy Xamarin.iOS zapewnia deweloperom dostęp do interfejsów API wątkowych platformy .NET, zarówno jawnie w przypadku korzystania z wątków (System.Threading.Thread, System.Threading.ThreadPool), jak i niejawnie w przypadku używania asynchronicznych wzorców delegatów lub metod BeginXXX, a także pełnego zakresu interfejsów API obsługujących bibliotekę równoległą zadań.

Platforma Xamarin zdecydowanie zaleca używanie biblioteki równoległej zadań (TPL) do kompilowania aplikacji z kilku powodów:

  • Domyślny harmonogram TPL deleguje wykonywanie zadań do puli wątków, co z kolei dynamicznie zwiększa liczbę wątków potrzebnych podczas procesu, unikając scenariusza, w którym zbyt wiele wątków kończy się rywalizacją o czas procesora CPU.
  • Łatwiej jest myśleć o operacjach pod względem zadań TPL. Można łatwo manipulować nimi, planować je, serializować ich wykonywanie lub uruchamiać wiele równolegle z bogatym zestawem interfejsów API.
  • Jest to podstawa programowania przy użyciu nowych rozszerzeń języka asynchronicznego języka C#.

Pula wątków powoli zwiększa liczbę wątków zgodnie z potrzebami na podstawie liczby rdzeni procesora CPU dostępnych w systemie, obciążenia systemu i wymagań aplikacji. Tę pulę wątków można użyć, wywołując metody w System.Threading.ThreadPool programie lub używając wartości domyślnej System.Threading.Tasks.TaskScheduler (część platform równoległych).

Zazwyczaj deweloperzy używają wątków, gdy muszą tworzyć dynamiczne aplikacje i nie chcą blokować głównej pętli uruchamiania interfejsu użytkownika.

Tworzenie dynamicznych aplikacji

Dostęp do elementów interfejsu użytkownika powinien być ograniczony do tego samego wątku, który uruchamia pętlę główną aplikacji. Jeśli chcesz wprowadzić zmiany w głównym interfejsie użytkownika z wątku, należy umieścić kod w kolejce przy użyciu obiektu NSObject.InvokeOnMainThread, w następujący sposób:

MyThreadedRoutine ()  
{  
    var result = DoComputation ();  

    // we want to update an object that is managed by the main
    // thread; To do so, we need to ensure that we only access
    // this from the main thread:

    InvokeOnMainThread (delegate {  
        label.Text = "The result is: " + result;  
    });
}

Powyższe wywołanie kodu wewnątrz delegata w kontekście głównego wątku bez powodowania warunków wyścigu, które mogą potencjalnie spowodować awarię aplikacji.

Wątkowanie i odzyskiwanie pamięci

W trakcie wykonywania Objective-C środowisko uruchomieniowe utworzy i zwolni obiekty. Jeśli obiekty są oflagowane dla "automatycznego wydania", Objective-C środowisko uruchomieniowe zwolni te obiekty do bieżącego NSAutoReleasePoolwątku . Platforma Xamarin.iOS tworzy jedną pulę NSAutoRelease dla każdego wątku z elementu System.Threading.ThreadPool i dla głównego wątku. Rozszerzenie obejmuje wszystkie wątki utworzone przy użyciu domyślnego elementu TaskScheduler w system.Threading.Tasks.

Jeśli tworzysz własne wątki przy użyciu System.Threading programu , musisz podać własną NSAutoRelease pulę, aby zapobiec wyciekowi danych. Aby to zrobić, po prostu opakuj wątek w następującym fragcie kodu:

void MyThreadStart (object arg)
{
   using (var ns = new NSAutoReleasePool ()){
      // Your code goes here.
   }
}

Uwaga: ponieważ platforma Xamarin.iOS 5.2 nie musi już udostępniać własnych NSAutoReleasePool , ponieważ zostanie automatycznie udostępniona.