diff --git a/Source/Tool/Building/BuildContext.cs b/Source/Tool/Building/BuildContext.cs index e8c12f46..4f92792c 100644 --- a/Source/Tool/Building/BuildContext.cs +++ b/Source/Tool/Building/BuildContext.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Threading; @@ -21,7 +22,8 @@ public class BuildContext : BuildInfo, IBuildDistributor { private readonly IPackageContext _packageContext; private readonly FindProjectItemDelegate _findProjectItem; - private readonly List<ProjectItem> _buildingProjects = new List<ProjectItem>(); + private readonly List<ProjectItem> _buildingProjects; + private readonly object _buildingProjectsLockObject; /* ReSharper disable PrivateFieldCanBeConvertedToLocalVariable * @@ -95,7 +97,7 @@ public override BuildedProjectsCollection BuildedProjects get { return _buildedProjects; } } - public override IEnumerable<ProjectItem> BuildingProjects + public override IReadOnlyList<ProjectItem> BuildingProjects { get { return _buildingProjects; } } @@ -149,6 +151,8 @@ public void CancelBuild() public BuildContext(IPackageContext packageContext, FindProjectItemDelegate findProjectItem) { _buildedProjects = new BuildedProjectsCollection(); + _buildingProjects = new List<ProjectItem>(); + _buildingProjectsLockObject = ((ICollection)_buildingProjects).SyncRoot; _packageContext = packageContext; _findProjectItem = findProjectItem; @@ -280,6 +284,7 @@ private bool GetProjectItem(BuildProjectContextEntry projectEntry, out ProjectIt IDictionary<string, string> projectProperties = projectEntry.Properties; if (projectProperties.ContainsKey("Configuration") && projectProperties.ContainsKey("Platform")) { + // TODO: Use find by FullNameProjectDefinition for the Batch Build only. string projectConfiguration = projectProperties["Configuration"]; string projectPlatform = projectProperties["Platform"]; var projectDefinition = new FullNameProjectDefinition(projectFile, projectConfiguration, projectPlatform); @@ -378,7 +383,10 @@ private void BuildEvents_OnBuildProjectBegin( throw new InvalidOperationException(); } - _buildingProjects.Add(currentProject); + lock (_buildingProjectsLockObject) + { + _buildingProjects.Add(currentProject); + } ProjectState projectState; switch (_buildAction) @@ -425,9 +433,12 @@ private void BuildEvents_OnBuildProjectDone(string project, string projectconfig throw new InvalidOperationException(); } - _buildingProjects.Remove(currentProject); + lock (_buildingProjectsLockObject) + { + _buildingProjects.Remove(currentProject); + } - var buildedProject = _buildedProjects[currentProject]; + BuildedProject buildedProject = _buildedProjects[currentProject]; buildedProject.Success = success; ProjectState projectState; @@ -536,8 +547,12 @@ private void BuildEvents_OnBuildBegin(vsBuildScope scope, vsBuildAction action) _buildCancelled = false; _buildCancelledInternally = false; - _buildingProjects.Clear(); + _buildedProjects.Clear(); + lock (_buildingProjectsLockObject) + { + _buildingProjects.Clear(); + } _buildedSolution = null; _buildingSolution = new BuildedSolution(_packageContext.GetDTE().Solution); @@ -588,7 +603,11 @@ private void BuildEvents_OnBuildDone() _buildedSolution = _buildingSolution; _buildingSolution = null; - _buildingProjects.Clear(); + + lock (_buildingProjectsLockObject) + { + _buildingProjects.Clear(); + } _buildFinishTime = DateTime.Now; _currentState = BuildState.Done; diff --git a/Source/Tool/Building/BuildInfo.cs b/Source/Tool/Building/BuildInfo.cs index 4965bf6f..8da85226 100644 --- a/Source/Tool/Building/BuildInfo.cs +++ b/Source/Tool/Building/BuildInfo.cs @@ -23,7 +23,7 @@ public abstract class BuildInfo public abstract BuildedProjectsCollection BuildedProjects { get; } - public abstract IEnumerable<ProjectItem> BuildingProjects { get; } + public abstract IReadOnlyList<ProjectItem> BuildingProjects { get; } public abstract BuildedSolution BuildedSolution { get; } diff --git a/Source/Tool/Building/BuildedProjectsCollection.cs b/Source/Tool/Building/BuildedProjectsCollection.cs index 76186bdd..d35981ed 100644 --- a/Source/Tool/Building/BuildedProjectsCollection.cs +++ b/Source/Tool/Building/BuildedProjectsCollection.cs @@ -5,6 +5,7 @@ namespace AlekseyNagovitsyn.BuildVision.Tool.Building { + // TODO: thread-safety. public class BuildedProjectsCollection : List<BuildedProject> { public int BuildSuccessCount @@ -30,7 +31,7 @@ public BuildedProject this[ProjectItem pi] { get { - var proj = this.FirstOrDefault(p => p.UniqueName == pi.UniqueName && p.Configuration == pi.Configuration && p.Platform == pi.Platform); + var proj = Find(p => p.UniqueName == pi.UniqueName && p.Configuration == pi.Configuration && p.Platform == pi.Platform); if (proj == null) { proj = new BuildedProject(pi.UniqueName, pi.FullName, pi.Configuration, pi.Platform); @@ -40,18 +41,5 @@ public BuildedProject this[ProjectItem pi] return proj; } } - - /// <summary> - /// Get <see cref="BuildedProject"/> by <see cref="ProjectItem.UniqueName"/>. - /// If not exists, returns <c>null</c>. - /// </summary> - public BuildedProject this[string uniqueName] - { - get - { - var proj = this.FirstOrDefault(p => p.UniqueName == uniqueName); - return proj; - } - } } } \ No newline at end of file diff --git a/Source/Tool/Models/ProjectItem.cs b/Source/Tool/Models/ProjectItem.cs index 57add406..7f916295 100644 --- a/Source/Tool/Models/ProjectItem.cs +++ b/Source/Tool/Models/ProjectItem.cs @@ -218,7 +218,6 @@ public DateTime? BuildStartTime { _buildStartTime = value; OnPropertyChanged("BuildStartTime"); - OnPropertyChanged("BuildStartTime2"); OnPropertyChanged("BuildElapsedTime"); } } @@ -238,7 +237,6 @@ public DateTime? BuildFinishTime { _buildFinishTime = value; OnPropertyChanged("BuildFinishTime"); - OnPropertyChanged("BuildFinishTime2"); OnPropertyChanged("BuildElapsedTime"); } } @@ -250,10 +248,13 @@ public TimeSpan? BuildElapsedTime { get { - if (BuildStartTime == null || BuildFinishTime == null) + if (_buildStartTime == null) return null; - return BuildFinishTime.Value.Subtract(BuildStartTime.Value); + if (_buildFinishTime == null) + return DateTime.Now.Subtract(_buildStartTime.Value); + + return _buildFinishTime.Value.Subtract(_buildStartTime.Value); } } @@ -447,6 +448,11 @@ public void UpdatePostBuildProperties(BuildedProject buildedProjectInfo) ErrorsBox = buildedProjectInfo.ErrorsBox; } + public void RaiseBuildElapsedTimeChanged() + { + OnPropertyChanged("BuildElapsedTime"); + } + private void UpdateProperties() { Project project = _storageProject; diff --git a/Source/Tool/Tool.cs b/Source/Tool/Tool.cs index 51949ee2..950a69cf 100644 --- a/Source/Tool/Tool.cs +++ b/Source/Tool/Tool.cs @@ -1,4 +1,6 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.Linq; using System.Windows.Controls; @@ -31,6 +33,7 @@ public class Tool private readonly SolutionEvents _solutionEvents; private bool _buildErrorIsNavigated; + private string _origTextCurrentState; public Tool( IPackageContext packageContext, @@ -215,8 +218,6 @@ private void OutputInStatusBar(string str, bool freeze) _dteStatusBar.FreezeOutput(1); } - private string _origTextCurrentState; - private void BuildEvents_OnBuildProcess() { try @@ -227,6 +228,13 @@ private void BuildEvents_OnBuildProcess() _viewModel.TextCurrentState = msg; OutputInStatusBar(msg, true); //_dte.SuppressUI = false; + + IReadOnlyList<ProjectItem> buildingProjects = _buildContext.BuildingProjects; + lock (((ICollection)buildingProjects).SyncRoot) + { + for (int i = 0; i < buildingProjects.Count; i++) + buildingProjects[i].RaiseBuildElapsedTimeChanged(); + } } catch (Exception ex) {