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ê.