Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Os usuários esperam que um aplicativo permaneça responsivo enquanto ele faz a computação, independentemente do tipo de computador. Isso significa coisas diferentes para aplicativos diferentes. Para alguns, isso se traduz em fornecer física mais realista, carregar dados do disco ou da Web mais rapidamente, apresentar rapidamente cenas complexas e navegar entre páginas, encontrar direções em um snap ou processar dados rapidamente. Independentemente do tipo de computação, os usuários querem que seu aplicativo reaja à sua entrada e elimine as instâncias em que ele parece não responder enquanto "pensa".
Seu aplicativo é controlado por eventos, o que significa que seu código executa o trabalho em resposta a um evento e fica ocioso até o próximo. O código da plataforma para interface do usuário (layout, entrada, disparo de eventos etc.) e o código do aplicativo para interface do usuário são executados na mesma thread da interface do usuário. Somente uma instrução pode ser executada nesse thread de cada vez, portanto, se o código do aplicativo demorar muito para processar um evento, a estrutura não poderá executar layout ou gerar novos eventos que representem a interação do usuário. A capacidade de resposta do seu aplicativo está relacionada à disponibilidade do thread da interface para processar o trabalho.
Você precisa usar o thread de UI para fazer quase todas as alterações no thread de UI, incluindo a criação de tipos de UI e o acesso aos membros. Você não pode atualizar a interface do usuário a partir de um thread em segundo plano, mas pode postar uma mensagem para ele usando CoreDispatcher.RunAsync para fazer com que o código seja executado lá.
Observação A única exceção é que há um thread de renderização separado que pode aplicar alterações de interface do usuário que não afetarão a forma como a entrada é tratada ou o layout básico. Por exemplo, muitas animações e transições que não afetam o layout podem ser executadas neste thread de renderização.
Instanciação de elemento de atraso
Alguns dos estágios mais lentos em um aplicativo podem incluir inicialização e alternância de exibições. Não trabalhe mais do que o necessário para exibir a interface que o usuário vê inicialmente. Por exemplo, não crie a interface do usuário para elementos progressivos e o conteúdo de popups.
- Use de atributo x:Load ou x:DeferLoadStrategy para atrasar a instanciação de elementos.
- Insira elementos programaticamente na árvore sob demanda.
CoreDispatcher.RunIdleAsync filas funcionam para que o thread de interface do usuário seja processado quando ele não estiver ocupado.
Usar APIs assíncronas
Para ajudar a manter seu aplicativo responsivo, a plataforma fornece versões assíncronas de muitas de suas APIs. Uma API assíncrona garante que seu thread de execução ativo nunca seja bloqueado por um período significativo de tempo. Quando você chamar uma API do thread de interface do usuário, use a versão assíncrona se ela estiver disponível. Para obter mais informações sobre programação com padrões assíncronos
Delegar o trabalho para threads em segundo plano
Escreva manipuladores de eventos para retornar rapidamente. Nos casos em que uma quantidade não trivial de trabalho precisa ser executada, agende-o em um thread em segundo plano e retorne.
Você pode agendar o trabalho de forma assíncrona usando o operador await em C#, o operador Await no Visual Basic ou delegados no C++. Mas isso não garante que o trabalho agendado será executado em um thread em segundo plano. Muitas das APIs da Plataforma Universal do Windows (UWP) agendam o trabalho no thread de segundo plano para você, mas se você chamar o código do aplicativo usando apenas await ou um delegado, você executa esse delegado ou método no thread da interface do usuário. Você precisa dizer explicitamente quando deseja executar o código do aplicativo em um thread em segundo plano. No C# e no Visual Basic, você pode fazer isso passando código para Task.Run.
Lembre-se de que os elementos da interface do usuário só podem ser acessados do thread de interface do usuário. Use o thread da interface do usuário para acessar elementos da interface do usuário antes de iniciar o trabalho em segundo plano e/ou usar CoreDispatcher.RunAsync ou CoreDispatcher.RunIdleAsync no thread em segundo plano.
Um exemplo de trabalho que pode ser executado em um thread em segundo plano é o cálculo da IA do computador em um jogo. O código que calcula o próximo movimento do computador pode levar muito tempo para ser executado.
public class AsyncExample
{
private async void NextMove_Click(object sender, RoutedEventArgs e)
{
// The await causes the handler to return immediately.
await System.Threading.Tasks.Task.Run(() => ComputeNextMove());
// Now update the UI with the results.
// ...
}
private async System.Threading.Tasks.Task ComputeNextMove()
{
// Perform background work here.
// Don't directly access UI elements from this method.
}
}
Public Class AsyncExample ' ... Private Async Sub NextMove_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Await Task.Run(Function() ComputeNextMove()) ' update the UI with results End Sub Private Async Function ComputeNextMove() As Task ' ... End Function ' ... End Class
Neste exemplo, o manipulador de NextMove_Click
retorna no espera para manter a thread da UI responsiva. Mas a execução retoma nesse manipulador depois que ComputeNextMove
(que é executado em um thread em segundo plano) é concluído. O código restante no manipulador atualiza a interface do usuário com os resultados.
Observação também há um ThreadPool e ThreadPoolTimer API para a UWP, que pode ser usada para cenários semelhantes. Para obter mais informações, consulte Threading e programação assíncrona.