C# VSIX 定期将状态消息写入输出 window
C# VSIX Write status messages to the output window periodically
我开始使用 Visual Studio 扩展,并希望在我任务的某些里程碑期间将状态消息写入输出 window 以报告其进度。
我正在使用命令从上下文菜单中触发任务。这是它的 Execute 方法的模拟示例:
private void Execute(object sender, EventArgs e)
{
ThreadHelper.ThrowIfNotOnUIThread();
var paneGuid = Guid.NewGuid();
var outputWindow = (IVsOutputWindow)Package.GetGlobalService(typeof(SVsOutputWindow));
outputWindow.CreatePane(ref paneGuid, "My Window", 1, 1);
outputWindow.GetPane(ref paneGuid, out var outputPane);
outputPane.Activate();
outputPane.OutputString("Starting...\n");
Thread.Sleep(2000);
outputPane.OutputString("1...\n");
Thread.Sleep(2000);
outputPane.OutputString("2...\n");
Thread.Sleep(2000);
outputPane.OutputString("3...\n");
Thread.Sleep(2000);
outputPane.OutputString("Finished");
}
输出 window 在 Execute 方法完成后显示,而不是按写入显示输出。
如何让它立即显示并定期写消息?
更新:解决方案
正如 JHBonarius 在下面所建议的那样,解决方案是将逻辑移动到异步任务中并调用 UI 线程根据需要写入输出 window:
private void Execute(object sender, EventArgs e)
{
ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
var paneGuid = Guid.NewGuid();
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var outputWindow = (IVsOutputWindow)Package.GetGlobalService(typeof(SVsOutputWindow));
outputWindow.CreatePane(ref paneGuid, "My Window", 1, 1);
outputWindow.GetPane(ref paneGuid, out var outputPane);
outputPane.Activate();
outputPane.OutputString("Starting...\n");
await TaskScheduler.Default;
// Call to some async task
await Task.Delay(2000);
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
outputPane.OutputString("1...\n");
await TaskScheduler.Default;
// Call to some async task
await Task.Delay(2000);
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
outputPane.OutputString("2...\n");
await TaskScheduler.Default;
// Call to some async task
await Task.Delay(2000);
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
outputPane.OutputString("3...\n");
await TaskScheduler.Default;
// Call to some async task
await Task.Delay(2000);
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
outputPane.OutputString("Finished");
await TaskScheduler.Default;
});
}
谢谢,
周杰伦
您在 UI 线程上并且不 return 控制(而是通过睡眠锁定线程)。因此 UI 无法呈现。您可能希望将其重写为单独的方法或异步方法。
我开始使用 Visual Studio 扩展,并希望在我任务的某些里程碑期间将状态消息写入输出 window 以报告其进度。
我正在使用命令从上下文菜单中触发任务。这是它的 Execute 方法的模拟示例:
private void Execute(object sender, EventArgs e)
{
ThreadHelper.ThrowIfNotOnUIThread();
var paneGuid = Guid.NewGuid();
var outputWindow = (IVsOutputWindow)Package.GetGlobalService(typeof(SVsOutputWindow));
outputWindow.CreatePane(ref paneGuid, "My Window", 1, 1);
outputWindow.GetPane(ref paneGuid, out var outputPane);
outputPane.Activate();
outputPane.OutputString("Starting...\n");
Thread.Sleep(2000);
outputPane.OutputString("1...\n");
Thread.Sleep(2000);
outputPane.OutputString("2...\n");
Thread.Sleep(2000);
outputPane.OutputString("3...\n");
Thread.Sleep(2000);
outputPane.OutputString("Finished");
}
输出 window 在 Execute 方法完成后显示,而不是按写入显示输出。
如何让它立即显示并定期写消息?
更新:解决方案
正如 JHBonarius 在下面所建议的那样,解决方案是将逻辑移动到异步任务中并调用 UI 线程根据需要写入输出 window:
private void Execute(object sender, EventArgs e)
{
ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
var paneGuid = Guid.NewGuid();
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var outputWindow = (IVsOutputWindow)Package.GetGlobalService(typeof(SVsOutputWindow));
outputWindow.CreatePane(ref paneGuid, "My Window", 1, 1);
outputWindow.GetPane(ref paneGuid, out var outputPane);
outputPane.Activate();
outputPane.OutputString("Starting...\n");
await TaskScheduler.Default;
// Call to some async task
await Task.Delay(2000);
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
outputPane.OutputString("1...\n");
await TaskScheduler.Default;
// Call to some async task
await Task.Delay(2000);
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
outputPane.OutputString("2...\n");
await TaskScheduler.Default;
// Call to some async task
await Task.Delay(2000);
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
outputPane.OutputString("3...\n");
await TaskScheduler.Default;
// Call to some async task
await Task.Delay(2000);
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
outputPane.OutputString("Finished");
await TaskScheduler.Default;
});
}
谢谢, 周杰伦
您在 UI 线程上并且不 return 控制(而是通过睡眠锁定线程)。因此 UI 无法呈现。您可能希望将其重写为单独的方法或异步方法。