Gerenciar vários threads em código gerenciado

Se você tiver uma extensão VSPackage gerenciada que chama métodos assíncronos ou tem operações que são executadas em threads diferentes do thread da interface do usuário do Visual Studio, você deve seguir as diretrizes fornecidas abaixo. Você pode manter o thread da interface do usuário responsivo porque ele não precisa aguardar a conclusão do trabalho em outro thread. Você pode tornar seu código mais eficiente, porque você não tem threads extras que ocupam espaço de pilha, e você pode torná-lo mais confiável e mais fácil de depurar porque você evita deadlocks e código sem resposta.

Em geral, você pode alternar do thread da interface do usuário para um thread diferente, ou vice-versa. Quando o método retorna, o thread atual é o thread do qual ele foi originalmente chamado.

Importante

As diretrizes a seguir usam as APIs no Microsoft.VisualStudio.Threading namespace, em particular, a JoinableTaskFactory classe. As APIs neste namespace são novas no Visual Studio 2013. Você pode obter uma instância de a JoinableTaskFactory da ThreadHelper propriedade ThreadHelper.JoinableTaskFactory.

Alternar do thread da interface do usuário para um thread em segundo plano

  1. Se você estiver no thread da interface do usuário e quiser fazer um trabalho assíncrono em um thread em segundo plano, use Task.Run():

    await Task.Run(async delegate{
        // Now you're on a separate thread.
    });
    // Now you're back on the UI thread.
    
    
  2. Se você estiver no thread da interface do usuário e quiser bloquear de forma síncrona enquanto estiver executando o trabalho em um thread em segundo plano, use a propriedade TaskScheduler.Default dentro Runde TaskScheduler :

    // using Microsoft.VisualStudio.Threading;
    ThreadHelper.JoinableTaskFactory.Run(async delegate {
        await TaskScheduler.Default;
        // You're now on a separate thread.
        DoSomethingSynchronous();
        await OrSomethingAsynchronous();
    });
    

Alternar de um thread em segundo plano para o thread da interface do usuário

  1. Se você estiver em um thread em segundo plano e quiser fazer algo no thread da interface do usuário, use SwitchToMainThreadAsync:

    // Switch to main thread
    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
    

    Você pode usar o método para alternar para o SwitchToMainThreadAsync thread da interface do usuário. Esse método posta uma mensagem para o thread da interface do usuário com a continuação do método assíncrono atual e também se comunica com o restante da estrutura de threading para definir a prioridade correta e evitar deadlocks.

    Se o método de thread em segundo plano não for assíncrono e você não puder torná-lo assíncrono, você ainda poderá usar a await sintaxe para alternar para o thread da interface do usuário encapsulando seu trabalho com Run, como neste exemplo:

    ThreadHelper.JoinableTaskFactory.Run(async delegate {
        // Switch to main thread
        await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
        // Do your work on the main thread here.
    });