バックグラウンドでかなり長いバッチジョブを実行することがある拡張機能を作成しており、実際に機能していることをユーザーに適切に示す必要があります。
可能であれば、「ソリューションの準備」ダイアログなど、VS2012がすでに使用している読み込みポップアップ/ialogを使用すると便利です。拡張機能からそのポップアップのインスタンスを作成する方法を知っている人はいますか?
そうでない場合、良い選択肢はありますか?ステータス文字列とプログレスバーを表示できることが望ましいでしょう。
バックグラウンドでかなり長いバッチジョブを実行することがある拡張機能を作成しており、実際に機能していることをユーザーに適切に示す必要があります。
可能であれば、「ソリューションの準備」ダイアログなど、VS2012がすでに使用している読み込みポップアップ/ialogを使用すると便利です。拡張機能からそのポップアップのインスタンスを作成する方法を知っている人はいますか?
そうでない場合、良い選択肢はありますか?ステータス文字列とプログレスバーを表示できることが望ましいでしょう。
自分で進行状況ダイアログを表示する方法を探していましたが、最終的にCommonMessagePump
、操作の完了に時間がかかる場合にVisualStudioに表示されるのと同じ待機ダイアログを提供するというクラスに出くわしました。
使用するのは少し面倒ですが、かなりうまくいくようです。操作に2秒程度かかるまで表示されず、キャンセルもサポートします。
というクラスがItem
あり、そのクラスにというプロパティが含まれていてName
、これらのアイテムのリストを処理したい場合は、次のように実行できます。
void MyLengthyOperation(IList<Item> items)
{
CommonMessagePump msgPump = new CommonMessagePump();
msgPump.AllowCancel = true;
msgPump.EnableRealProgress = true;
msgPump.WaitTitle = "Doing stuff..."
msgPump.WaitText = "Please wait while doing stuff.";
CancellationTokenSource cts = new CancellationTokenSource();
Task task = Task.Run(() =>
{
for (int i = 0; i < items.Count; i++)
{
cts.Token.ThrowIfCancellationRequested();
msgPump.CurrentStep = i + 1;
msgPump.ProgressText = String.Format("Processing Item {0}/{1}: {2}", i + 1, msgPump.TotalSteps, items[i].Name);
// Do lengthy stuff on item...
}
}, cts.Token);
var exitCode = msgPump.ModalWaitForHandles(((IAsyncResult)task).AsyncWaitHandle);
if (exitCode == CommonMessagePumpExitCode.UserCanceled || exitCode == CommonMessagePumpExitCode.ApplicationExit)
{
cts.Cancel();
msgPump = new CommonMessagePump();
msgPump.AllowCancel = false;
msgPump.EnableRealProgress = false;
// Wait for the async operation to actually cancel.
msgPump.ModalWaitForHandles(((IAsyncResult)task).AsyncWaitHandle);
}
if (!task.IsCanceled)
{
try
{
task.Wait();
}
catch (AggregateException aex)
{
MessageBox.Show(aex.InnerException.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}