/// <summary> /// Updates the Visual Studio user interface. This is performed asynchronously /// by default which will result in better performance. /// </summary> /// <param name="synchronously"> /// Optionally specifies that the update should be performed immediately, /// before the method returns. /// </param> internal static void UpdateVisualStudioUI(bool synchronously = false) { ThreadHelper.ThrowIfNotOnUIThread(); var vsShell = (IVsUIShell)RaspberryDebugPackage.GetGlobalService(typeof(IVsUIShell)); if (vsShell != null) { var hr = vsShell.UpdateCommandUI(synchronously ? 1 : 0); Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(hr); } }
/// <summary> /// Executes an asynchronous action that does not return a result within the context of a /// Visual Studio progress dialog. You may make nested calls and this may also be called /// from any thread. /// </summary> /// <typeparam name="TResult">The action result type.</typeparam> /// <param name="description">The operation description.</param> /// <param name="action">The action.</param> /// <returns>The tracking <see cref="Task"/>.</returns> public static async Task <TResult> ExecuteWithProgressAsync <TResult>(string description, Func <Task <TResult> > action) { Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(description), nameof(description)); Covenant.Requires <ArgumentNullException>(action != null, nameof(action)); await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (progressDialog == null) { Covenant.Assert(operationStack.Count == 0); rootDescription = description; operationStack.Push(description); var dialogFactory = (IVsThreadedWaitDialogFactory)RaspberryDebugPackage.GetGlobalService((typeof(SVsThreadedWaitDialogFactory))); dialogFactory.CreateInstance(out progressDialog); progressDialog.StartWaitDialog( szWaitCaption: progressCaption, szWaitMessage: description, szProgressText: null, varStatusBmpAnim: null, szStatusBarText: $"[{LogName}]{description}", iDelayToShowDialog: 0, fIsCancelable: false, fShowMarqueeProgress: true); } else { Covenant.Assert(operationStack.Count > 0); operationStack.Push(description); progressDialog.UpdateProgress( szUpdatedWaitMessage: progressCaption, szProgressText: description, szStatusBarText: null, iCurrentStep: 0, iTotalSteps: 0, fDisableCancel: true, pfCanceled: out var cancelled); } var orgCursor = Cursor.Current; try { Cursor.Current = Cursors.WaitCursor; return(await action().ConfigureAwait(false)); } finally { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); Cursor.Current = orgCursor; var currentDescription = operationStack.Pop(); if (operationStack.Count == 0) { progressDialog.EndWaitDialog(out var cancelled); progressDialog = null; rootDescription = null; } else { progressDialog.UpdateProgress( szUpdatedWaitMessage: currentDescription, szProgressText: null, szStatusBarText: rootDescription, iCurrentStep: 0, iTotalSteps: 0, fDisableCancel: true, pfCanceled: out var cancelled); } } }