Skip to content

Commit c81596c

Browse files
Modifying Notify Events to Invoke through Threads to avoid possible DeadLocks
1 parent ddb3b2d commit c81596c

5 files changed

Lines changed: 25 additions & 7 deletions

File tree

src/ThunderDesign.Net-PCL.Threading/Collections/ObservableCollectionThreadSafe.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Collections.ObjectModel;
3+
using System.Collections.Specialized;
34
using System.ComponentModel;
45
using System.Threading;
56
using ThunderDesign.Net.Threading.Extentions;
@@ -16,6 +17,7 @@ public ObservableCollectionThreadSafe(List<T> list) : base(list) { }
1617
#endregion
1718

1819
#region event handlers
20+
public override event NotifyCollectionChangedEventHandler CollectionChanged;
1921
protected override event PropertyChangedEventHandler PropertyChanged;
2022
#endregion
2123

@@ -198,13 +200,26 @@ public ObservableCollectionThreadSafe(List<T> list) : base(list) { }
198200

199201
public T GetItemByIndex(int index)
200202
{
201-
return this[index];
203+
_ReaderWriterLockSlim.EnterReadLock();
204+
try
205+
{
206+
return this[index];
207+
}
208+
finally
209+
{
210+
_ReaderWriterLockSlim.ExitReadLock();
211+
}
202212
}
203213

204214
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
205215
{
206216
this.NotifyPropertyChanged(PropertyChanged, e.PropertyName);
207217
}
218+
219+
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
220+
{
221+
this.NotifyCollectionChanged(CollectionChanged, e);
222+
}
208223
#endregion
209224

210225
#region variables

src/ThunderDesign.Net-PCL.Threading/Collections/ObservableDictionaryThreadSafe.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public ObservableDictionaryThreadSafe(IDictionary<TKey, TValue> dictionary, IEqu
2020
#region event handlers
2121
public event NotifyCollectionChangedEventHandler CollectionChanged;
2222
public event PropertyChangedEventHandler PropertyChanged;
23+
2324
#endregion
2425

2526
#region properties
@@ -100,7 +101,6 @@ protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args
100101
{
101102
this.NotifyCollectionChanged(CollectionChanged, args);
102103
}
103-
104104
#endregion
105105
}
106106
}

src/ThunderDesign.Net-PCL.Threading/Extentions/INotifyCollectionChangedExtension.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Specialized;
2+
using ThunderDesign.Net.Threading.HelperClasses;
23

34
namespace ThunderDesign.Net.Threading.Extentions
45
{
@@ -9,9 +10,10 @@ public static void NotifyCollectionChanged(
910
NotifyCollectionChangedEventHandler handler,
1011
NotifyCollectionChangedEventArgs args)
1112
{
12-
//ThreadHelper.RunAndForget(() => handler?.Invoke(sender, args));
13+
// Calling 'Invoke' can cause DeadLocks and 'BeginInvoke' can cause System.PlatformNotSupportedException errors so calling Invoke from within a Thread
14+
//handler?.Invoke(sender, args);
1315
//handler?.BeginInvoke(sender, args, ar => { }, null);
14-
handler?.Invoke(sender, args);
16+
ThreadHelper.RunAndForget(() => handler?.Invoke(sender, args));
1517
}
1618
}
1719
}

src/ThunderDesign.Net-PCL.Threading/Extentions/INotifyPropertyChangedExtension.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.ComponentModel;
22
using System.Runtime.CompilerServices;
3+
using ThunderDesign.Net.Threading.HelperClasses;
34

45
namespace ThunderDesign.Net.Threading.Extentions
56
{
@@ -19,9 +20,10 @@ public static void NotifyPropertyChanged(
1920
PropertyChangedEventHandler handler,
2021
PropertyChangedEventArgs args)
2122
{
22-
//ThreadHelper.RunAndForget(() => handler?.Invoke(sender, args));
23+
// Calling 'Invoke' can cause DeadLocks and 'BeginInvoke' can cause System.PlatformNotSupportedException errors so calling Invoke from within a Thread
24+
//handler?.Invoke(sender, args);
2325
//handler?.BeginInvoke(sender, args, ar => { }, null);
24-
handler?.Invoke(sender, args);
26+
ThreadHelper.RunAndForget(() => handler?.Invoke(sender, args));
2527
}
2628

2729
public static bool SetProperty<T>(

src/ThunderDesign.Net-PCL.Threading/HelperClasses/ThreadHelper.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,5 @@ public static void RunAndForget(Action action, Action<Exception> handler = null)
3333
TaskContinuationOptions.OnlyOnFaulted);
3434
}
3535
}
36-
3736
}
3837
}

0 commit comments

Comments
 (0)