在托管代码中管理多个线程
如果你有一个托管的 VSPackage 扩展,该扩展调用异步方法或在 Visual Studio UI 线程以外的线程上执行操作,则应遵循以下指南。 可以保持 UI 线程响应,因为它不需要等待另一个线程上的工作完成。 可以提高代码的效率,因为没有占用堆栈空间的额外线程,并且可以使其更可靠、更易于调试,因为避免死锁和无响应代码。
通常,你可以从 UI 线程切换到其他线程,反之亦然。 此方法返回时,当前线程是最初从中调用它的线程。
重要
以下准则使用命名空间中的 Microsoft.VisualStudio.Threading API, JoinableTaskFactory 特别是类。 此命名空间中的 API 是 Visual Studio 2013 中的新增 API。 可以从属性ThreadHelper.JoinableTaskFactory
获取实例。JoinableTaskFactory ThreadHelper
从 UI 线程切换到后台线程
如果位于 UI 线程上,并且想要在后台线程上执行异步工作,请使用
Task.Run()
:await Task.Run(async delegate{ // Now you're on a separate thread. }); // Now you're back on the UI thread.
如果在 UI 线程上,并且希望在后台线程上执行工作时同步阻止,请使用TaskScheduler
TaskScheduler.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 线程
如果使用的是后台线程,并且想要在 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. });