Skip to content
This repository has been archived by the owner on Oct 4, 2021. It is now read-only.

Commit

Permalink
[Core] Make MSBuildPropertyGroupEvaluated thread safe
Browse files Browse the repository at this point in the history
Adding a new .json file to a ASP.NET Core 3.1 project resulted in the
files not being displayed in the Properties folder due to the project
configuration's Properties being updated on a background thread on
saving and the UI thread reading these properties to determine if a
file is visible in the Solution pad. Switch to using a concurrent
dictionary in MSBuildPropertyGroupEvaluated.

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
  at System.Collections.Generic.Dictionary`2+ValueCollection+Enumerator[TKey,TValue].MoveNext () [0x00085] in mono-x64/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/Dictionary.cs:1628
  at MonoDevelop.Projects.MSBuild.MSBuildEvaluatedPropertyCollection+<MonoDevelop-Projects-IPropertySet-GetProperties>d__11.MoveNext () [0x0008e] in monodevelop/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildPropertyGroupEvaluated.cs:207
  at MonoDevelop.Projects.Project+<GetVisibleFiles>d__143.MoveNext () [0x0017d] in monodevelop/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs:1231
  at MonoDevelop.Ide.Gui.Pads.ProjectPad.FolderNodeBuilder.GetFolderContent (MonoDevelop.Projects.Project project, System.String folder, System.Collections.Generic.List`1[MonoDevelop.Projects.ProjectFile]& files, System.Collections.Generic.List`1[System.String]& folders) [0x00149] in monodevelop/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/FolderNodeBuilder.cs:87
  at MonoDevelop.Ide.Gui.Pads.ProjectPad.FolderNodeBuilder.BuildChildNodes (MonoDevelop.Ide.Gui.Components.ITreeBuilder builder, System.Object dataObject) [0x00048] in monodevelop/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/FolderNodeBuilder.cs:74
  at MonoDevelop.Ide.Gui.Components.ExtensibleTreeView+TransactedTreeBuilder.FillNode () [0x00082] in monodevelop/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Components/TransactedTreeBuilder.cs:522
  • Loading branch information
mrward authored and monojenkins committed Jan 3, 2020
1 parent e08e58f commit 021be87
Showing 1 changed file with 5 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Xml.Linq;
using MonoDevelop.Core;
Expand All @@ -32,7 +33,7 @@ namespace MonoDevelop.Projects.MSBuild
{
class MSBuildPropertyGroupEvaluated: MSBuildNode, IMSBuildPropertyGroupEvaluated, IMSBuildProjectObject
{
protected Dictionary<string,IMSBuildPropertyEvaluated> properties = new Dictionary<string, IMSBuildPropertyEvaluated> (StringComparer.OrdinalIgnoreCase);
protected ConcurrentDictionary<string, IMSBuildPropertyEvaluated> properties = new ConcurrentDictionary<string, IMSBuildPropertyEvaluated> (StringComparer.OrdinalIgnoreCase);
MSBuildEngine engine;

internal MSBuildPropertyGroupEvaluated (MSBuildProject parent)
Expand Down Expand Up @@ -70,7 +71,7 @@ internal void SetProperty (string key, IMSBuildPropertyEvaluated value)

internal void SetProperties (Dictionary<string,IMSBuildPropertyEvaluated> properties)
{
this.properties = properties;
this.properties = new ConcurrentDictionary<string, IMSBuildPropertyEvaluated> (properties, StringComparer.OrdinalIgnoreCase);
}

public IEnumerable<IMSBuildPropertyEvaluated> GetProperties ()
Expand All @@ -80,7 +81,7 @@ public IEnumerable<IMSBuildPropertyEvaluated> GetProperties ()

internal bool RemoveProperty (string name)
{
return properties.Remove (name);
return properties.TryRemove (name, out _);
}

public string GetValue (string name, string defaultValue = null)
Expand Down Expand Up @@ -280,7 +281,7 @@ void IPropertyGroupListener.PropertyRemoved (MSBuildProperty prop)
// that property group property.
if (ep.IsNew || !prop.IsNew) {
ep.IsNew = false;
properties.Remove (ep.Name);
properties.TryRemove (ep.Name, out _);
}
}
}
Expand Down

0 comments on commit 021be87

Please sign in to comment.