diff options
author | Alan McGovern <alan.mcgovern@gmail.com> | 2011-11-23 20:01:00 +0400 |
---|---|---|
committer | Alan McGovern <alan.mcgovern@gmail.com> | 2011-11-23 20:03:42 +0400 |
commit | 3ab70a991b9c685b0d4a786965ab1273441d1f5d (patch) | |
tree | d067495f65902635449dc798bc8f1ec949972cee | |
parent | 0bab6c562f01a3b8dc77d79450d7d50b17a5c384 (diff) |
[WebReferences] Do not update the webreferences while blocking the UI
WebReferences are now updated in a background thread. The call to the
WebReferencesChanged event is proxied to the main UI thread if it is
not on the UI thread so that everywhere which hooks into this event
does not have to be modified to sync back.
2 files changed, 63 insertions, 21 deletions
diff --git a/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences.Commands/WebReferenceCommandHandler.cs b/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences.Commands/WebReferenceCommandHandler.cs index 1900caa49a..9ea1aa29ab 100644 --- a/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences.Commands/WebReferenceCommandHandler.cs +++ b/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences.Commands/WebReferenceCommandHandler.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using MonoDevelop.Components.Commands; using MonoDevelop.Core; using MonoDevelop.Projects; @@ -8,12 +9,17 @@ using MonoDevelop.Ide.Gui.Components; using MonoDevelop.Ide; using System.Collections.Generic; using MonoDevelop.Core.Assemblies; +using System.Threading.Tasks; namespace MonoDevelop.WebReferences.Commands { /// <summary>Defines the properties and methods for the WebReferenceCommandHandler class.</summary> public class WebReferenceCommandHandler : NodeCommandHandler { + StatusBarContext UpdateReferenceContext { + get; set; + } + /// <summary>Execute the command for adding a new web reference to a project.</summary> [CommandHandler (MonoDevelop.WebReferences.WebReferenceCommands.Add)] public void NewWebReference() @@ -51,35 +57,61 @@ namespace MonoDevelop.WebReferences.Commands } } + [CommandUpdateHandler (MonoDevelop.WebReferences.WebReferenceCommands.Update)] + [CommandUpdateHandler (MonoDevelop.WebReferences.WebReferenceCommands.UpdateAll)] + void CanUpdateWebReferences (CommandInfo ci) + { + // This does not appear to work. + ci.Enabled = UpdateReferenceContext == null; + } + /// <summary>Execute the command for updating a web reference in a project.</summary> [CommandHandler (MonoDevelop.WebReferences.WebReferenceCommands.Update)] public void Update() { - using (StatusBarContext sbc = IdeApp.Workbench.StatusBar.CreateContext ()) { - sbc.BeginProgress (GettextCatalog.GetString ("Updating web reference")); - sbc.AutoPulse = true; - WebReferenceItem item = (WebReferenceItem) CurrentNode.DataItem; - DispatchService.BackgroundDispatchAndWait (item.Update); - IdeApp.ProjectOperations.Save (item.Project); - IdeApp.Workbench.StatusBar.ShowMessage("Updated Web Reference " + item.Name); - } + UpdateReferences (new [] { (WebReferenceItem) CurrentNode.DataItem }); } - + /// <summary>Execute the command for updating all web reference in a project.</summary> [CommandHandler (MonoDevelop.WebReferences.WebReferenceCommands.UpdateAll)] public void UpdateAll() { - using (StatusBarContext sbc = IdeApp.Workbench.StatusBar.CreateContext ()) { - sbc.BeginProgress (GettextCatalog.GetString ("Updating web references")); - sbc.AutoPulse = true; - DotNetProject project = ((WebReferenceFolder) CurrentNode.DataItem).Project; - List<WebReferenceItem> items = new List<WebReferenceItem> (WebReferencesService.GetWebReferenceItems (project)); - DispatchService.BackgroundDispatchAndWait (delegate { - foreach (var item in items) - item.Update(); + DotNetProject project = ((WebReferenceFolder) CurrentNode.DataItem).Project; + UpdateReferences (WebReferencesService.GetWebReferenceItems (project).ToArray ()); + } + + void UpdateReferences (IList<WebReferenceItem> items) + { + try { + UpdateReferenceContext = IdeApp.Workbench.StatusBar.CreateContext (); + UpdateReferenceContext.BeginProgress (GettextCatalog.GetPluralString ("Updating web reference", "Updating web references", items.Count)); + + DispatchService.ThreadDispatch (() => { + for (int i = 0; i < items.Count; i ++) { + DispatchService.GuiDispatch (() => UpdateReferenceContext.SetProgressFraction (Math.Max (0.1, (double)i / items.Count))); + items [i].Update(); + } + + DispatchService.GuiDispatch (() => { + // Make sure that we save all relevant projects, there should only be 1 though + foreach (var project in items.Select (i =>i.Project).Distinct ()) + IdeApp.ProjectOperations.Save (project); + + IdeApp.Workbench.StatusBar.ShowMessage(GettextCatalog.GetPluralString ("Updated Web Reference {0}", "Updated Web References", items.Count, items[0].Name)); + DisposeUpdateContext (); + }); }); - IdeApp.ProjectOperations.Save (project); - IdeApp.Workbench.StatusBar.ShowMessage("Updated all Web References"); + } catch { + DisposeUpdateContext (); + throw; + } + } + + void DisposeUpdateContext () + { + if (UpdateReferenceContext != null) { + UpdateReferenceContext.Dispose (); + UpdateReferenceContext = null; } } diff --git a/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences/WebReferencesService.cs b/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences/WebReferencesService.cs index ee4de272d8..275c328391 100644 --- a/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences/WebReferencesService.cs +++ b/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences/WebReferencesService.cs @@ -48,8 +48,18 @@ namespace MonoDevelop.WebReferences public static void NotifyWebReferencesChanged (DotNetProject project) { - if (WebReferencesChanged != null) - WebReferencesChanged (null, new WebReferencesChangedArgs (project)); + // This is called from a background thread when webreferences are being + // updated asynchronously, so lets keep things simple for the users of + // this event and just ensure we proxy it to the main thread. + if (MonoDevelop.Ide.DispatchService.IsGuiThread) { + if (WebReferencesChanged != null) + WebReferencesChanged (null, new WebReferencesChangedArgs (project)); + } else { + MonoDevelop.Ide.DispatchService.GuiDispatch (() => { + if (WebReferencesChanged != null) + WebReferencesChanged (null, new WebReferencesChangedArgs (project)); + }); + } } public static event EventHandler<WebReferencesChangedArgs> WebReferencesChanged; |