Skip to content

Commit 00c4785

Browse files
Merge pull request #15 from ShawnLaMountain/main
When WaitOnNotifying is true for collections updates from other threa…
2 parents 69d10bc + 58b2814 commit 00c4785

File tree

74 files changed

+31575
-151
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+31575
-151
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,11 @@ This can be overwritten durring creation or by setting Property `WaitOnNotifyPro
6767
Observable Collections now Wait when calling `CollectionChanged` Event.
6868
This can be overwritten durring creation or by setting Property `WaitOnNotifyCollectionChanged`. Default value is `true`.
6969

70-
*(TIP: If you experience Dead Locks change this value to `false`.)*
70+
*(TIP: If you experience Dead Locks change this value to `false`.)*
71+
72+
73+
## Breaking changes from v1.0.9 to v1.0.10!
74+
75+
Observable Objects Property `WaitOnNotifyPropertyChanged` has been renamed to Property `WaitOnNotifying`.
76+
77+
Observable Collections Property `WaitOnNotifyCollectionChanged` has been removed and now uses Property `WaitOnNotifying`.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.1.32127.271
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleThreadTest", "SimpleThreadTest\SimpleThreadTest.csproj", "{4E3DF2B7-56C4-4DA8-8F62-15795C1CA7BC}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThunderDesign.Net-PCL.Threading", "..\..\..\src\ThunderDesign.Net-PCL.Threading\ThunderDesign.Net-PCL.Threading.csproj", "{8B8D5C7F-FA81-46BB-81B6-9245F6B8DED6}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{4E3DF2B7-56C4-4DA8-8F62-15795C1CA7BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{4E3DF2B7-56C4-4DA8-8F62-15795C1CA7BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{4E3DF2B7-56C4-4DA8-8F62-15795C1CA7BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
19+
{4E3DF2B7-56C4-4DA8-8F62-15795C1CA7BC}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{8B8D5C7F-FA81-46BB-81B6-9245F6B8DED6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{8B8D5C7F-FA81-46BB-81B6-9245F6B8DED6}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{8B8D5C7F-FA81-46BB-81B6-9245F6B8DED6}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{8B8D5C7F-FA81-46BB-81B6-9245F6B8DED6}.Release|Any CPU.Build.0 = Release|Any CPU
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {45DFC863-C602-4020-9301-9BAFD7F4DDF4}
30+
EndGlobalSection
31+
EndGlobal
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using SimpleThreadTest.DataObjects;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using ThunderDesign.Net.Threading.Collections;
8+
9+
namespace SimpleThreadTest.DataCollections
10+
{
11+
internal class ThreadTestCollection : ObservableCollectionThreadSafe<ThreadTestObject>
12+
{
13+
}
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using SimpleThreadTest.DataObjects;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using ThunderDesign.Net.Threading.Collections;
8+
using ThunderDesign.Net.Threading.DataCollections;
9+
10+
namespace SimpleThreadTest.DataCollections
11+
{
12+
public class ThreadTestDictionary : ObservableDataDictionary<int, ThreadTestObject>
13+
{
14+
}
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using SimpleThreadTest.DataObjects;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using ThunderDesign.Net_PCL.Threading.Collections;
8+
9+
namespace SimpleThreadTest.DataCollections
10+
{
11+
public class ThreadTestList : ListThreadSafe<ThreadTestObject>
12+
{
13+
}
14+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using ThunderDesign.Net.Threading.DataObjects;
7+
using ThunderDesign.Net.Threading.Extentions;
8+
9+
namespace SimpleThreadTest.DataObjects
10+
{
11+
public class ThreadTestObject : BindableDataObject<int>
12+
{
13+
#region properties
14+
public string Name
15+
{
16+
get { return this.GetProperty(ref _Name, _Locker); }
17+
set
18+
{
19+
//if (this.SetProperty(ref _Name, value, _Locker, true))
20+
// OnPropertyChanged(nameof(DisplayText));
21+
lock(_Locker)
22+
{
23+
if (this.SetProperty(ref _Name, value, true))
24+
OnPropertyChanged(nameof(DisplayText));
25+
26+
}
27+
}
28+
}
29+
30+
public int IncCounterWaitTimeSeconds
31+
{
32+
get { return this.GetProperty(ref _IncCounterWaitTimeSeconds, _Locker); }
33+
set { this.SetProperty(ref _IncCounterWaitTimeSeconds, value, _Locker, true); }
34+
}
35+
36+
public int DecCounterWaitTimeSeconds
37+
{
38+
get { return this.GetProperty(ref _DecCounterWaitTimeSeconds, _Locker); }
39+
set { this.SetProperty(ref _DecCounterWaitTimeSeconds, value, _Locker, true); }
40+
}
41+
42+
public long Counter
43+
{
44+
get { return this.GetProperty(ref _Counter, _Locker); }
45+
private set
46+
{
47+
if (this.SetProperty(ref _Counter, value, _Locker))
48+
OnPropertyChanged(nameof(DisplayText));
49+
}
50+
}
51+
52+
public string DisplayText
53+
{
54+
get { return Name + " = " + Counter.ToString(); }
55+
}
56+
#endregion
57+
58+
#region variables
59+
protected string _Name = String.Empty;
60+
protected int _IncCounterWaitTimeSeconds = 1;
61+
protected int _DecCounterWaitTimeSeconds = 1;
62+
protected long _Counter = 0;
63+
#endregion
64+
}
65+
}

samples/WinForms/SimpleThreadTest/SimpleThreadTest/Form1.Designer.cs

Lines changed: 85 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
using SimpleThreadTest.DataCollections;
2+
using SimpleThreadTest.DataObjects;
3+
using System.Collections.Specialized;
4+
using System.ComponentModel;
5+
using ThunderDesign.Net.Threading.HelperClasses;
6+
7+
namespace SimpleThreadTest
8+
{
9+
public partial class frmMain : Form
10+
{
11+
public frmMain()
12+
{
13+
InitializeComponent();
14+
//lbThreadOutput.DataSource = _ThreadTestList;
15+
//lbThreadOutput.DisplayMember = nameof(ThreadTestObject.DisplayText);
16+
//lbThreadOutput.ValueMember = nameof(ThreadTestObject.Id);
17+
//lbThreadOutput.data
18+
//lbThreadOutput.DataBind();
19+
//lbThreadOutput.ValueMember = nameof(ThreadTestObject.Counter_AsString);
20+
_ThreadTestCollection.CollectionChanged += OnThreadTestCollection_CollectionChanged;
21+
}
22+
23+
private void OnThreadTestCollection_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
24+
{
25+
switch (e.Action)
26+
{
27+
case NotifyCollectionChangedAction.Add:
28+
foreach (var item in e.NewItems)
29+
{
30+
if (item is ThreadTestObject)
31+
{
32+
((ThreadTestObject)item).PropertyChanged += OnThreadTestObjectPropertyChanged;
33+
}
34+
}
35+
OnRefreshDisplay(sender, new EventArgs());
36+
break;
37+
case NotifyCollectionChangedAction.Move:
38+
break;
39+
case NotifyCollectionChangedAction.Remove:
40+
foreach (var item in e.OldItems)
41+
{
42+
if (item is ThreadTestObject)
43+
{
44+
((ThreadTestObject)item).PropertyChanged -= OnThreadTestObjectPropertyChanged;
45+
}
46+
}
47+
OnRefreshDisplay(sender, new EventArgs());
48+
break;
49+
case NotifyCollectionChangedAction.Replace:
50+
break;
51+
case NotifyCollectionChangedAction.Reset:
52+
break;
53+
}
54+
}
55+
56+
private void OnThreadTestObjectPropertyChanged(object? sender, PropertyChangedEventArgs e)
57+
{
58+
if (!(sender is ThreadTestObject))
59+
return;
60+
61+
if (String.Equals(e.PropertyName, nameof(ThreadTestObject.DisplayText), StringComparison.OrdinalIgnoreCase))
62+
OnRefreshDisplay(sender, new EventArgs());
63+
}
64+
65+
private void OnRefreshDisplay(object? sender, EventArgs e)
66+
{
67+
if (lbThreadOutput.InvokeRequired)
68+
{
69+
//return;
70+
lbThreadOutput.Invoke(new EventHandler(OnRefreshDisplay), sender, e);
71+
return;
72+
}
73+
74+
lbThreadOutput.DataSource = null;
75+
lbThreadOutput.DataSource = _ThreadTestCollection;
76+
lbThreadOutput.DisplayMember = nameof(ThreadTestObject.DisplayText);
77+
lbThreadOutput.ValueMember = nameof(ThreadTestObject.Id);
78+
}
79+
80+
private async void BtnTest_Click(object sender, EventArgs e)
81+
{
82+
ThreadTestObject threadTestObject = new ThreadTestObject();
83+
threadTestObject.Id = 1;
84+
threadTestObject.Name = "Test 1";
85+
_ThreadTestCollection.Add(threadTestObject);
86+
87+
ThreadHelper.RunAndForget(() =>
88+
{
89+
Task.Delay(1000).GetAwaiter().GetResult();
90+
threadTestObject.Name = "Changed";
91+
});
92+
93+
//Task.Delay(5000).GetAwaiter().GetResult();
94+
95+
threadTestObject = new ThreadTestObject();
96+
threadTestObject.Id = 2;
97+
threadTestObject.Name = "Test 2";
98+
_ThreadTestCollection.Add(threadTestObject);
99+
100+
ThreadHelper.RunAndForget(() =>
101+
//Task.Run(()=>
102+
{
103+
ThreadTestObject threadTestObject2 = new ThreadTestObject();
104+
threadTestObject2.Id = 3;
105+
threadTestObject2.Name = "Test 3";
106+
_ThreadTestCollection.Add(threadTestObject2);
107+
108+
threadTestObject2 = new ThreadTestObject();
109+
threadTestObject2.Id = 4;
110+
threadTestObject2.Name = "Test 4";
111+
_ThreadTestCollection.Add(threadTestObject2);
112+
113+
threadTestObject2 = new ThreadTestObject();
114+
threadTestObject2.Id = 5;
115+
threadTestObject2.Name = "Test 5";
116+
_ThreadTestCollection.Add(threadTestObject2);
117+
});
118+
}
119+
120+
//private readonly ThreadTestDictionary _ThreadTestDictionary = new ThreadTestDictionary();
121+
//private readonly ThreadTestList _ThreadTestList = new ThreadTestList();
122+
private readonly ThreadTestCollection _ThreadTestCollection = new ThreadTestCollection();
123+
124+
private void btnRefresh_Click(object sender, EventArgs e)
125+
{
126+
lbThreadOutput.DataSource = null;
127+
lbThreadOutput.DataSource = _ThreadTestCollection;
128+
lbThreadOutput.DisplayMember = nameof(ThreadTestObject.DisplayText);
129+
lbThreadOutput.ValueMember = nameof(ThreadTestObject.Id);
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)