Threading no Xamarin.iOS

O runtime do Xamarin.iOS dá aos desenvolvedores acesso às APIs de threading do .NET, explicitamente ao usar threads (System.Threading.Thread, System.Threading.ThreadPool) e implicitamente ao usar os padrões delegados assíncronos ou os métodos BeginXXX, bem como a gama completa de APIs que dão suporte à Biblioteca Paralela de Tarefas.

O Xamarin recomenda fortemente que você use a TPL (Biblioteca Paralela de Tarefas ) para criar aplicativos por alguns motivos:

  • O agendador TPL padrão delegará a execução da tarefa ao pool de threads, o que, por sua vez, aumentará dinamicamente o número de threads necessários à medida que o processo ocorrer, evitando um cenário em que muitos threads acabem competindo por tempo de CPU.
  • É mais fácil pensar em operações em termos de Tarefas TPL. Você pode manipulá-los facilmente, agende-os, serialize sua execução ou inicie muitos em paralelo com um conjunto avançado de APIs.
  • É a base para a programação com as novas extensões de linguagem assíncrona do C#.

O pool de threads aumentará lentamente o número de threads conforme necessário com base no número de núcleos de CPU disponíveis no sistema, na carga do sistema e nas demandas do aplicativo. Você pode usar esse pool de threads invocando métodos no System.Threading.ThreadPool ou usando o padrão System.Threading.Tasks.TaskScheduler (parte das Estruturas Paralelas).

Normalmente, os desenvolvedores usam threads quando precisam criar aplicativos responsivos e não querem bloquear o loop de execução da interface do usuário main.

Desenvolvendo aplicativos responsivos

O acesso aos elementos da interface do usuário deve ser limitado ao mesmo thread que está executando o loop main para seu aplicativo. Se você quiser fazer alterações na interface do usuário main de um thread, deverá enfileirar o código usando NSObject.InvokeOnMainThread, desta forma:

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

O acima invoca o código dentro do delegado no contexto do thread main, sem causar nenhuma condição de corrida que possa causar falhas no aplicativo.

Threading e Coleta de Lixo

No decorrer da execução, o Objective-C runtime criará e liberará objetos. Se os objetos forem sinalizados para "liberação automática", o Objective-C runtime liberará esses objetos para o thread atual NSAutoReleasePool. O Xamarin.iOS cria um NSAutoRelease pool para cada thread do System.Threading.ThreadPool e para o thread main. Isso por extensão abrange todos os threads criados usando o TaskScheduler padrão em System.Threading.Tasks.

Se você criar seus próprios threads usando System.Threading , precisará fornecer seu próprio NSAutoRelease pool para evitar que os dados vazem. Para fazer isso, basta encapsular seu thread na seguinte parte do código:

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

Observação: como o Xamarin.iOS 5.2 não é mais necessário fornecer o seu próprio NSAutoReleasePool , pois um será fornecido automaticamente para você.