Skip to content

Commit

Permalink
Avoid race-condition where layers are loading and populating as map s…
Browse files Browse the repository at this point in the history
…tarts up.

Can cause `InvalidOperationException: Collection was modified; enumeration operation may not execute.` while map is loading.
Also listen to collection changed events first, to ensure we're always up to date.
  • Loading branch information
Morten Nielsen committed Jul 25, 2023
1 parent 5db7706 commit 060c729
Showing 1 changed file with 13 additions and 13 deletions.
26 changes: 13 additions & 13 deletions src/Toolkit/Toolkit/LayerContentDataSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,18 @@ private IEnumerable<Action> TrackLayerContentsRecursive(IEnumerable<ILayerConten
{
if (layers != null)
{
foreach (var layer in layers)
if (layers is INotifyCollectionChanged incc)
{
var listener = new WeakEventListener<LayerContentDataSource<T>, INotifyCollectionChanged, object?, NotifyCollectionChangedEventArgs>(this, incc)
{
OnEventAction = static (instance, source, eventArgs) => instance.Layers_CollectionChanged(source, eventArgs),
OnDetachAction = static (instance, source, weakEventListener) => source.CollectionChanged -= weakEventListener.OnEvent,
};
incc.CollectionChanged += listener.OnEvent;
yield return listener.Detach;
}

foreach (var layer in layers.ToArray())
{
if (layer is INotifyPropertyChanged inpc)
{
Expand All @@ -375,22 +386,11 @@ private IEnumerable<Action> TrackLayerContentsRecursive(IEnumerable<ILayerConten
yield return listener.Detach;
}

foreach (var sublayerAction in TrackLayerContentsRecursive(layer.SublayerContents))
foreach (var sublayerAction in TrackLayerContentsRecursive(layer.SublayerContents).ToArray())
{
yield return sublayerAction;
}
}

if (layers is INotifyCollectionChanged incc)
{
var listener = new WeakEventListener<LayerContentDataSource<T>, INotifyCollectionChanged, object?, NotifyCollectionChangedEventArgs>(this, incc)
{
OnEventAction = static (instance, source, eventArgs) => instance.Layers_CollectionChanged(source, eventArgs),
OnDetachAction = static (instance, source, weakEventListener) => source.CollectionChanged -= weakEventListener.OnEvent,
};
incc.CollectionChanged += listener.OnEvent;
yield return listener.Detach;
}
}
}

Expand Down

0 comments on commit 060c729

Please sign in to comment.