diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-02-21 16:11:30 +0100 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-02-21 16:11:30 +0100 |
| commit | 05e7cd5133826afd42d215e08c4874ee48ed49be (patch) | |
| tree | 2f449777278cc8b4805a4e80d7ee81b3863bc4a1 /src/GraphicObjects/Group.cs | |
| parent | 30b49efa1763ebdfe82f9d69e0e7bafcdd3b25a8 (diff) | |
implement ReaderWritelLockSlim to resolve threading issues
Diffstat (limited to 'src/GraphicObjects/Group.cs')
| -rw-r--r-- | src/GraphicObjects/Group.cs | 125 |
1 files changed, 78 insertions, 47 deletions
diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index 1b5847d4..e7604842 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -31,12 +31,15 @@ using System.Xml.Serialization; using Cairo; using System.Diagnostics; using System.Reflection; +using System.Threading; namespace Crow { public class Group : GraphicObject { + protected ReaderWriterLockSlim childrenRWLock = new ReaderWriterLockSlim(); + #region CTOR public Group () : base() {} public Group(Interface iface) : base(iface){} @@ -62,10 +65,13 @@ namespace Crow set { _multiSelect = value; } } public virtual void AddChild(GraphicObject g){ - lock (Children) { - g.Parent = this; - Children.Add (g); - } + childrenRWLock.EnterWriteLock(); + + g.Parent = this; + Children.Add (g); + + childrenRWLock.ExitWriteLock(); + g.RegisteredLayoutings = LayoutingType.None; g.LayoutChanged += OnChildLayoutChanges; g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); @@ -79,8 +85,11 @@ namespace Crow CurrentInterface.HoverWidget = null; } - lock (Children) - Children.Remove(child); + childrenRWLock.EnterWriteLock (); + + Children.Remove(child); + + childrenRWLock.ExitWriteLock (); if (child == largestChild && Width == Measure.Fit) searchLargestChild (); @@ -96,10 +105,13 @@ namespace Crow child.Dispose (); } public virtual void InsertChild (int idx, GraphicObject g) { - lock (Children) { - g.Parent = this; - Children.Insert (idx, g); - } + childrenRWLock.EnterWriteLock (); + + g.Parent = this; + Children.Insert (idx, g); + + childrenRWLock.ExitWriteLock (); + g.RegisteredLayoutings = LayoutingType.None; g.LayoutChanged += OnChildLayoutChanges; g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); @@ -109,15 +121,17 @@ namespace Crow } public virtual void ClearChildren() { - lock (Children) { - while (Children.Count > 0) { - GraphicObject g = Children [Children.Count - 1]; - g.LayoutChanged -= OnChildLayoutChanges; - Children.RemoveAt (Children.Count - 1); - g.Dispose (); - } + childrenRWLock.EnterWriteLock (); + + while (Children.Count > 0) { + GraphicObject g = Children [Children.Count - 1]; + g.LayoutChanged -= OnChildLayoutChanges; + Children.RemoveAt (Children.Count - 1); + g.Dispose (); } + childrenRWLock.ExitWriteLock (); + resetChildrenMaxSize (); this.RegisterForLayouting (LayoutingType.Sizing); @@ -128,20 +142,24 @@ namespace Crow { if (Children.Contains(w)) { - lock (Children) { - Children.Remove (w); - Children.Add (w); - } + childrenRWLock.EnterWriteLock (); + + Children.Remove (w); + Children.Add (w); + + childrenRWLock.ExitWriteLock (); } } public void putWidgetOnBottom(GraphicObject w) { if (Children.Contains(w)) { - lock (Children) { - Children.Remove (w); - Children.Insert (0, w); - } + childrenRWLock.EnterWriteLock (); + + Children.Remove (w); + Children.Insert (0, w); + + childrenRWLock.ExitWriteLock (); } } @@ -149,24 +167,31 @@ namespace Crow public override void OnDataSourceChanged (object sender, DataSourceChangeEventArgs e) { base.OnDataSourceChanged (this, e); - lock (Children) { - foreach (GraphicObject g in children) - if (g.localDataSourceIsNull & g.localLogicalParentIsNull) - g.OnDataSourceChanged (g, e); - } + + childrenRWLock.EnterReadLock (); + + foreach (GraphicObject g in children) + if (g.localDataSourceIsNull & g.localLogicalParentIsNull) + g.OnDataSourceChanged (g, e); + + childrenRWLock.ExitReadLock (); } public override GraphicObject FindByName (string nameToFind) { if (Name == nameToFind) return this; GraphicObject tmp = null; - lock (Children) { - foreach (GraphicObject w in Children) { - tmp = w.FindByName (nameToFind); - if (tmp != null) - break; - } + + childrenRWLock.EnterReadLock (); + + foreach (GraphicObject w in Children) { + tmp = w.FindByName (nameToFind); + if (tmp != null) + break; } + + childrenRWLock.ExitReadLock (); + return tmp; } public override bool Contains (GraphicObject goToFind) @@ -207,10 +232,11 @@ namespace Crow { base.OnLayoutChanges (layoutType); + childrenRWLock.EnterReadLock (); //position smaller objects in group when group size is fit switch (layoutType) { case LayoutingType.Width: - foreach (GraphicObject c in Children){ + foreach (GraphicObject c in Children) { if (c.Width.Units == Unit.Percent) c.RegisterForLayouting (LayoutingType.Width); else @@ -226,6 +252,7 @@ namespace Crow } break; } + childrenRWLock.ExitReadLock (); } protected override void onDraw (Context gr) { @@ -239,11 +266,13 @@ namespace Crow gr.Clip (); } - lock (Children) { + childrenRWLock.EnterReadLock (); + foreach (GraphicObject g in Children) { g.Paint (ref gr); } - } + + childrenRWLock.ExitReadLock (); gr.Restore (); } protected override void UpdateCache (Context ctx) @@ -268,16 +297,18 @@ namespace Crow gr.Clip (); } - lock (Children) { - foreach (GraphicObject c in Children) { - if (!c.Visible) - continue; - if (Clipping.Contains (c.Slot + ClientRectangle.Position) == RegionOverlap.Out) - continue; - c.Paint (ref gr); - } + childrenRWLock.EnterReadLock (); + + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; + if (Clipping.Contains (c.Slot + ClientRectangle.Position) == RegionOverlap.Out) + continue; + c.Paint (ref gr); } + childrenRWLock.ExitReadLock (); + #if DEBUG_CLIP_RECTANGLE Clipping.stroke (gr, Color.Amaranth.AdjustAlpha (0.8)); #endif |