在托管代码中管理多个线程

如果你有一个托管的 VSPackage 扩展,该扩展调用异步方法或在 Visual Studio UI 线程以外的线程上执行操作,则应遵循以下指南。 可以保持 UI 线程响应,因为它不需要等待另一个线程上的工作完成。 可以提高代码的效率,因为没有占用堆栈空间的额外线程,并且可以使其更可靠、更易于调试,因为避免死锁和无响应代码。

通常,你可以从 UI 线程切换到其他线程,反之亦然。 此方法返回时,当前线程是最初从中调用它的线程。

重要

以下准则使用命名空间中的 Microsoft.VisualStudio.Threading API, JoinableTaskFactory 特别是类。 此命名空间中的 API 是 Visual Studio 2013 中的新增 API。 可以从属性ThreadHelper.JoinableTaskFactory获取实例。JoinableTaskFactoryThreadHelper

从 UI 线程切换到后台线程

  1. 如果位于 UI 线程上,并且想要在后台线程上执行异步工作,请使用 Task.Run()

    await Task.Run(async delegate{
        // Now you're on a separate thread.
    });
    // Now you're back on the UI thread.
    
    
  2. 如果在 UI 线程上,并且希望在后台线程上执行工作时同步阻止,请使用TaskSchedulerTaskScheduler.Default以下属性:Run

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

从后台线程切换到 UI 线程

  1. 如果使用的是后台线程,并且想要在 UI 线程上执行某些操作,请使用 SwitchToMainThreadAsync

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

    可以使用该方法 SwitchToMainThreadAsync 切换到 UI 线程。 此方法使用当前异步方法的延续将消息发布到 UI 线程,还与线程框架的其余部分通信以设置正确的优先级并避免死锁。

    如果后台线程方法不是异步方法,并且无法使其异步,则仍可以通过包装你的工作Run方式来使用await语法切换到 UI 线程,如以下示例所示:

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