2

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

ありがとう、ジェイ

4

1 に答える 1

0

UI スレッドを使用していて、制御を返しません (代わりにスレッドをスリープ状態でロックします)。したがって、UI はレンダリングできません。これを別のメソッドまたは非同期メソッドに書き直すことができます。

于 2021-03-24T07:04:23.250 に答える