diff --git a/src/WeakEvent.Tests/WeakEventLockingTests.cs b/src/WeakEvent.Tests/WeakEventLockingTests.cs
new file mode 100644
index 0000000..38b43d2
--- /dev/null
+++ b/src/WeakEvent.Tests/WeakEventLockingTests.cs
@@ -0,0 +1,22 @@
+using Xunit.Abstractions;
+
+namespace ByteAether.WeakEvent.Tests;
+public class WeakEventLockingTests(ITestOutputHelper output)
+{
+ private readonly ITestOutputHelper _output = output;
+
+ [Fact]
+ public async Task Handler_CanUnsubscribeItself()
+ {
+ WeakEvent e = new();
+ Action? handler = null;
+ handler = () =>
+ {
+ _output.WriteLine("Handler executing...");
+ e.Unsubscribe(handler!);
+ };
+
+ e.Subscribe(handler);
+ await e.PublishAsync();
+ }
+}
\ No newline at end of file
diff --git a/src/WeakEvent/WeakEvent.cs b/src/WeakEvent/WeakEvent.cs
index 2c70254..979e40e 100644
--- a/src/WeakEvent/WeakEvent.cs
+++ b/src/WeakEvent/WeakEvent.cs
@@ -153,7 +153,21 @@ public abstract class WeakEventBase
///
/// Number of alive subscribers currently registered to the event.
///
- public int SubscriberCount => _handlers.Count(x => x.IsAlive);
+ public int SubscriberCount
+ {
+ get
+ {
+ _lock.Wait();
+ try
+ {
+ return _handlers.Count(x => x.IsAlive);
+ }
+ finally
+ {
+ _lock.Release();
+ }
+ }
+ }
///
/// Subscribes the specified delegate handler to the event.
@@ -170,7 +184,15 @@ protected void Subscribe(Delegate handler)
throw new ArgumentNullException(nameof(handler));
}
- _handlers.Add(new WeakEventHandler(handler));
+ _lock.Wait();
+ try
+ {
+ _handlers.Add(new WeakEventHandler(handler));
+ }
+ finally
+ {
+ _lock.Release();
+ }
}
///
@@ -185,7 +207,15 @@ protected bool Unsubscribe(Delegate handler)
throw new ArgumentNullException(nameof(handler));
}
- return _handlers.RemoveAll(weh => weh.Matches(handler)) > 0;
+ _lock.Wait();
+ try
+ {
+ return _handlers.RemoveAll(weh => weh.Matches(handler)) > 0;
+ }
+ finally
+ {
+ _lock.Release();
+ }
}
///
@@ -196,20 +226,22 @@ protected bool Unsubscribe(Delegate handler)
/// The cancellation token to cancel the operation.
protected async Task PublishAsync(List