Gérer plusieurs threads dans le code managé

Si vous avez une extension VSPackage managée qui appelle des méthodes asynchrones ou a des opérations qui s’exécutent sur des threads autres que le thread d’interface utilisateur Visual Studio, vous devez suivre les instructions ci-dessous. Vous pouvez maintenir le thread d’interface utilisateur réactif, car il n’a pas besoin d’attendre que le travail sur un autre thread se termine. Vous pouvez rendre votre code plus efficace, car vous n’avez pas de threads supplémentaires qui prennent de l’espace de pile et vous pouvez le rendre plus fiable et plus facile à déboguer, car vous évitez les blocages et le code non répond.

En général, vous pouvez passer du thread d’interface utilisateur à un autre thread, ou inversement. Lorsque la méthode est retournée, le thread actuel est le thread à partir duquel il a été appelé à l’origine.

Important

Les instructions suivantes utilisent les API dans l’espace Microsoft.VisualStudio.Threading de noms, en particulier la JoinableTaskFactory classe. Les API de cet espace de noms sont nouvelles dans Visual Studio 2013. Vous pouvez obtenir une instance d’une JoinableTaskFactory instance à partir de la ThreadHelper propriété ThreadHelper.JoinableTaskFactory.

Passer du thread d’interface utilisateur à un thread d’arrière-plan

  1. Si vous êtes sur le thread d’interface utilisateur et que vous souhaitez effectuer un travail asynchrone sur un thread d’arrière-plan, utilisez Task.Run():

    await Task.Run(async delegate{
        // Now you're on a separate thread.
    });
    // Now you're back on the UI thread.
    
    
  2. Si vous êtes sur le thread d’interface utilisateur et que vous souhaitez bloquer de façon synchrone pendant que vous effectuez du travail sur un thread d’arrière-plan, utilisez la propriété TaskScheduler.Default à l’intérieur :TaskScheduler Run

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

Passer d’un thread d’arrière-plan au thread d’interface utilisateur

  1. Si vous êtes sur un thread d’arrière-plan et que vous souhaitez faire quelque chose sur le thread d’interface utilisateur, utilisez SwitchToMainThreadAsync:

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

    Vous pouvez utiliser la SwitchToMainThreadAsync méthode pour basculer vers le thread d’interface utilisateur. Cette méthode publie un message sur le thread d’interface utilisateur avec la continuation de la méthode asynchrone actuelle, et communique également avec le reste de l’infrastructure de thread pour définir la priorité correcte et éviter les blocages.

    Si votre méthode de thread d’arrière-plan n’est pas asynchrone et que vous ne pouvez pas la rendre asynchrone, vous pouvez toujours utiliser la await syntaxe pour basculer vers le thread d’interface utilisateur en encapsulant votre travail avec Run, comme dans cet exemple :

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