Como: gerenciar vários threads em código gerenciadoHow to: Manage multiple threads in managed code

Se você tiver uma extensão de VSPackage gerenciada que chama os métodos assíncronos ou tem operações executadas em threads diferentes do thread de interface de usuário do Visual Studio, você deve seguir as diretrizes abaixo.If you have a managed VSPackage extension that calls asynchronous methods or has operations that execute on threads other than the Visual Studio UI thread, you should follow the guidelines given below. Você pode manter o thread de interface do usuário responsiva porque ele não precisa aguardar o trabalho em outro thread para concluir.You can keep the UI thread responsive because it doesn't need to wait for work on another thread to complete. Você pode tornar seu código mais eficiente, porque você não tem threads extras que ocupam espaço na pilha, e você pode torná-lo mais confiável e fácil de depurar porque você evita deadlocks e travamentos.You can make your code more efficient, because you don't have extra threads that take up stack space, and you can make it more reliable and easier to debug because you avoid deadlocks and hangs.

Em geral, você pode alternar do thread de interface do usuário para um thread diferente, ou vice-versa.In general, you can switch from the UI thread to a different thread, or vice versa. Quando o método retorna, o thread atual é o thread do qual ele foi originalmente chamado.When the method returns, the current thread is the thread from which it was originally called.

Important

As diretrizes a seguir usam as APIs na Microsoft.VisualStudio.Threading namespace, em particular, o JoinableTaskFactory classe.The following guidelines use the APIs in the Microsoft.VisualStudio.Threading namespace, in particular, the JoinableTaskFactory class. As APIs neste namespace são novas no Visual Studio 2013Visual Studio 2013.The APIs in this namespace are new in Visual Studio 2013Visual Studio 2013. Você pode obter uma instância de um JoinableTaskFactory do ThreadHelper propriedade ThreadHelper.JoinableTaskFactory.You can get an instance of a JoinableTaskFactory from the ThreadHelper property ThreadHelper.JoinableTaskFactory.

Alternar do thread de interface do usuário para um thread em segundo planoSwitch from the UI thread to a background thread

  1. Se você estiver usando o thread de interface do usuário e você deseja fazer o trabalho assíncrono em um thread em segundo plano, use Task.Run():If you are on the UI thread and you want to do asynchronous work on a background thread, 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 usando o thread de interface do usuário e você deseja bloquear sincronicamente enquanto você estiver executando o trabalho em um thread em segundo plano, use o TaskScheduler propriedade TaskScheduler.Default dentro de Run:If you are on the UI thread and you want to synchronously block while you are performing work on a background thread, use the TaskScheduler property TaskScheduler.Default inside Run:

    // 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 de interface do usuárioSwitch from a background thread to the UI thread

  1. Se você estiver em um thread em segundo plano e você deseja fazer algo no thread da interface do usuário, use SwitchToMainThreadAsync:If you're on a background thread and you want to do something on the UI thread, use SwitchToMainThreadAsync:

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

    Você pode usar o SwitchToMainThreadAsync método para alternar para o thread de interface do usuário.You can use the SwitchToMainThreadAsync method to switch to the UI thread. Esse método envia uma mensagem para o thread de interface do usuário com a continuação do método assíncrona atual e também se comunica com o restante do framework threading para definir a prioridade correta e evitar deadlocks.This method posts a message to the UI thread with the continuation of the current asynchronous method, and also communicates with the rest of the threading framework to set the correct priority and avoid deadlocks.

    Se seu método de thread em segundo plano não é assíncrono e não é torná-la assíncrona, você ainda pode usar o await sintaxe para alternar para o thread de interface do usuário, encapsulando seu trabalho com Run, como neste exemplo:If your background thread method isn't asynchronous and you can't make it asynchronous, you can still use the await syntax to switch to the UI thread by wrapping your work with Run, as in this example:

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