I'm getting started with Visual Studio Extensions and would like to write status messages to the output window during certain milestones of my task to report it's progress.
I'm using a command to trigger the task from a context menu. Here is a mocked up example of it's Execute method:
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");
}
Rather than showing the output as it is written, the output window is shown after the Execute method has finished.
How do I get it to show straight away and to write messages periodically?
UPDATE: SOLUTION
As suggested below by JHBonarius the solution is to move the logic into an async task and to call the UI thread to write to the output window as required:
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;
});
}
Thanks, Jay