Threading in Xamarin.iOS

Die Xamarin.iOS-Runtime gewährt Entwicklern Zugriff auf die .NET-Threading-APIs, sowohl explizit bei Verwendung von Threads (System.Threading.Thread, System.Threading.ThreadPool) als auch implizit bei Verwendung der asynchronen Delegatmuster oder der BeginXXX-Methoden sowie auf den vollständigen Bereich von APIs, die die Task Parallel Library unterstützen.

Xamarin empfiehlt dringend, die Task Parallel Library (TPL) zum Erstellen von Anwendungen aus einigen Gründen zu verwenden:

  • Der Standard-TPL-Scheduler delegiert die Taskausführung an den Threadpool, wodurch die Anzahl der Threads, die während des Prozesses benötigt werden, dynamisch erhöht wird, während gleichzeitig ein Szenario vermieden wird, in dem zu viele Threads um die CPU-Zeit konkurrieren.
  • Es ist einfacher, über Vorgänge in Bezug auf TPL-Aufgaben nachzudenken. Sie können sie einfach bearbeiten, planen, ihre Ausführung serialisieren oder viele parallel mit einer vielzahl von APIs starten.
  • Es ist die Grundlage für die Programmierung mit den neuen asynchronen C#-Spracherweiterungen.

Der Threadpool erhöht die Anzahl der Threads je nach Bedarf langsam basierend auf der Anzahl der auf dem System verfügbaren CPU-Kerne, der Systemauslastung und den Anforderungen Ihrer Anwendung. Sie können diesen Threadpool entweder durch Aufrufen von Methoden in System.Threading.ThreadPool oder mithilfe des Standardwerts System.Threading.Tasks.TaskScheduler (Teil der Parallel Frameworks) verwenden.

In der Regel verwenden Entwickler Threads, wenn sie reaktionsfähige Anwendungen erstellen müssen und die Standard Ui-Ausführungsschleife nicht blockieren möchten.

Entwickeln von reaktionsfähigen Anwendungen

Der Zugriff auf UI-Elemente sollte auf denselben Thread beschränkt sein, in dem die Standard-Schleife für Ihre Anwendung ausgeführt wird. Wenn Sie Änderungen an der Standard Ui aus einem Thread vornehmen möchten, sollten Sie den Code wie folgt mithilfe von NSObject.InvokeOnMainThread in die Warteschlange stellen:

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;  
    });
}

Mit dem obigen Code wird der Code innerhalb des Delegaten im Kontext des Standard Threads aufgerufen, ohne dass Racebedingungen verursacht werden, die ihre Anwendung möglicherweise abstürzen könnten.

Threading und Garbage Collection

Im Laufe der Ausführung erstellt und gibt die Objective-C Runtime Objekte frei. Wenn Objekte für "automatische Freigabe" gekennzeichnet sind, gibt die Objective-C Runtime diese Objekte für den aktuellen NSAutoReleasePoolthread frei. Xamarin.iOS erstellt einen NSAutoRelease Pool für jeden Thread aus und System.Threading.ThreadPool für den Standard Threads. Diese Erweiterung deckt alle Threads ab, die mit dem Standardmäßigen TaskScheduler in System.Threading.Tasks erstellt wurden.

Wenn Sie ihre eigenen Threads mit erstellen System.Threading , müssen Sie Einen eigenen NSAutoRelease Pool bereitstellen, um zu verhindern, dass die Daten verloren gehen. Um dies zu tun, schließen Sie ihren Thread einfach in den folgenden Codeabschnitt ein:

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

Hinweis: Seit Xamarin.iOS 5.2 müssen Sie keine eigenen NSAutoReleasePool Mehr bereitstellen, da eine automatisch für Sie bereitgestellt wird.