【问题标题】:C# VSIX Write status messages to the output window periodicallyC# VSIX 定期将状态消息写入输出窗口
【发布时间】:2021-03-24 06:30:27
【问题描述】:

我开始使用 Visual Studio 扩展,并希望在我的任务的某些里程碑期间将状态消息写入输出窗口以报告其进度。

我正在使用命令从上下文菜单中触发任务。这是它的 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");
}

不是在写入时显示输出,而是在 Execute 方法完成后显示输出窗口。

如何让它立即显示并定期写入消息?

更新:解决方案

正如下面 JHBonarius 所建议的,解决方案是将逻辑移动到异步任务中,并根据需要调用 UI 线程以写入输出窗口:

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;
    });
}

谢谢, 周杰伦

【问题讨论】:

  • 您可以考虑使用await Task.Delay(2000); 而不是线程睡眠来简化此操作。
  • 谢谢,这是一个有趣的选择,虽然在这种情况下 Thread.Sleep(2000);只是被用作复制行为的占位符。这些将被各种等待的异步任务所取代。

标签: c# vsix output-window


【解决方案1】:

您在 UI 线程上并且不返回控制权(而是通过睡眠锁定线程)。因此 UI 无法呈现。您可能希望将其重写为单独的方法或异步方法。

【讨论】:

    猜你喜欢
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 2017-02-04
    • 2016-03-31
    • 2011-02-14
    • 2011-10-26
    相关资源
    最近更新 更多