Condividi tramite


Threading in Xamarin.iOS

Il runtime di Xamarin.iOS consente agli sviluppatori di accedere alle API di threading .NET, sia in modo esplicito quando si usano thread (System.Threading.Thread, System.Threading.ThreadPool) che in modo implicito quando si usano i modelli delegato asincroni o i metodi BeginXXX, nonché l'intera gamma di API che supportano Task Parallel Library.

Xamarin consiglia vivamente di usare Task Parallel Library (TPL) per la compilazione di applicazioni per alcuni motivi:

  • L'utilità di pianificazione TPL predefinita delega l'esecuzione dell'attività al pool di thread, che a sua volta aumenterà dinamicamente il numero di thread necessari man mano che avviene il processo, evitando allo stesso tempo uno scenario in cui troppi thread finiscono per competere per il tempo cpu.
  • È più facile considerare le operazioni in termini di attività TPL. È possibile modificarli facilmente, pianificarli, serializzare l'esecuzione o avviarne molti in parallelo con un set completo di API.
  • È la base per la programmazione con le nuove estensioni del linguaggio asincrono C#.

Il pool di thread aumenta lentamente il numero di thread in base alle esigenze in base al numero di core CPU disponibili nel sistema, al carico di sistema e alle richieste dell'applicazione. È possibile usare questo pool di thread richiamando i metodi in System.Threading.ThreadPool o usando il valore predefinito System.Threading.Tasks.TaskScheduler (parte dei framework paralleli).

In genere gli sviluppatori usano thread quando devono creare applicazioni reattive e non vogliono bloccare il ciclo di esecuzione principale dell'interfaccia utente.

Sviluppo di applicazioni reattive

L'accesso agli elementi dell'interfaccia utente deve essere limitato allo stesso thread che esegue il ciclo principale per l'applicazione. Se vuoi apportare modifiche all'interfaccia utente principale da un thread, devi accodare il codice usando NSObject.InvokeOnMainThread, come indicato di seguito:

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

Il codice precedente richiama il codice all'interno del delegato nel contesto del thread principale, senza causare race condition che potrebbero causare un arresto anomalo dell'applicazione.

Threading e Garbage Collection

Durante l'esecuzione, il Objective-C runtime creerà e rilascia oggetti. Se gli oggetti vengono contrassegnati per la "versione automatica", il Objective-C runtime rilascia tali oggetti all'oggetto corrente NSAutoReleasePooldel thread. Xamarin.iOS crea un NSAutoRelease pool per ogni thread da System.Threading.ThreadPool e per il thread principale. Questa estensione copre tutti i thread creati usando l'oggetto TaskScheduler predefinito in System.Threading.Tasks.

Se si creano thread personalizzati usando System.Threading è necessario fornire un pool personalizzato NSAutoRelease per impedire la perdita dei dati. A tale scopo, è sufficiente eseguire il wrapping del thread nel frammento di codice seguente:

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

Nota: poiché Xamarin.iOS 5.2 non è più necessario fornire il proprio NSAutoReleasePool perché ne verrà fornito automaticamente uno automaticamente.