diff --git a/README.md b/README.md index efdb431..e1eeee3 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Extensions for `System.Threading.Tasks.Task`, inspired by [John Thiriet](https:/ - AsyncAwaitBestPractices - An extension method to safely fire-and-forget a `Task`: - `SafeFireAndForget` + - `WeakEventManager` - [Usage instructions below](#asyncawaitbestpractices) - AsyncAwaitBestPractices.MVVM - Allows for `Task` to safely be used asynchronously with `ICommand`: @@ -60,6 +61,21 @@ async Task ExampleAsyncMethod() } ``` +An event implementation that enables the [garbage collector to collect an object without needing to unsubscribe event handlers](http://paulstovell.com/blog/weakevents): +- `WeakEventManager` + +```csharp +readonly WeakEventManager _weakEventManager = new WeakEventManager(); + +public event EventHandler CanExecuteChanged +{ + add => _weakEventManager.AddEventHandler(value); + remove => _weakEventManager.RemoveEventHandler(value); +} + +public void RaiseCanExecuteChanged() => _weakEventManager.HandleEvent(this, EventArgs.Empty, nameof(CanExecuteChanged)); +``` + ### AsyncAwaitBestPractices.MVVM Allows for `Task` to safely be used asynchronously with `ICommand`: diff --git a/Src/AsyncAwaitBestPractices.MVVM.nuspec b/Src/AsyncAwaitBestPractices.MVVM.nuspec index ac8c70f..1d7282e 100644 --- a/Src/AsyncAwaitBestPractices.MVVM.nuspec +++ b/Src/AsyncAwaitBestPractices.MVVM.nuspec @@ -2,7 +2,7 @@ AsyncAwaitBestPractices.MVVM - 1.0.1 + 1.1.0 Task Extensions for MVVM Brandon Minnick, John Thiriet Brandon Minnick @@ -14,12 +14,12 @@ Includes AsyncCommand and IAsyncCommand which allows ICommand to safely be used asynchronously with Task. task,fire and forget, threading, extensions, system.threading.tasks,async,await - + New In This Release: - - AsyncAwaitBestPractices.MVVM.AsyncCommand - - AsyncAwaitBestPractices.MVVM.IAsyncCommand + - Improved memory management + - Implemented WeakEventManager for AsyncCommand.CanExecuteChanged Copyright (c) 2018 Brandon Minnick diff --git a/Src/AsyncAwaitBestPractices.MVVM/AsyncCommand.cs b/Src/AsyncAwaitBestPractices.MVVM/AsyncCommand.cs index e7f7e89..5b56f6b 100644 --- a/Src/AsyncAwaitBestPractices.MVVM/AsyncCommand.cs +++ b/Src/AsyncAwaitBestPractices.MVVM/AsyncCommand.cs @@ -43,8 +43,8 @@ public AsyncCommand(Func execute, /// public event EventHandler CanExecuteChanged { - add { _weakEventManager.AddEventHandler(nameof(CanExecuteChanged), value); } - remove { _weakEventManager.RemoveEventHandler(nameof(CanExecuteChanged), value); } + add => _weakEventManager.AddEventHandler(value); + remove => _weakEventManager.RemoveEventHandler(value); } #endregion @@ -135,8 +135,8 @@ public AsyncCommand(Func execute, /// public event EventHandler CanExecuteChanged { - add { _weakEventManager.AddEventHandler(nameof(CanExecuteChanged), value); } - remove { _weakEventManager.RemoveEventHandler(nameof(CanExecuteChanged), value); } + add => _weakEventManager.AddEventHandler(value); + remove => _weakEventManager.RemoveEventHandler(value); } #endregion diff --git a/Src/AsyncAwaitBestPractices.nuspec b/Src/AsyncAwaitBestPractices.nuspec index e5e83e8..90489de 100644 --- a/Src/AsyncAwaitBestPractices.nuspec +++ b/Src/AsyncAwaitBestPractices.nuspec @@ -2,7 +2,7 @@ AsyncAwaitBestPractices - 1.0.1 + 1.1.0 Task Extensions for System.Threading.Tasks Brandon Minnick, John Thiriet Brandon Minnick @@ -19,8 +19,7 @@ task,fire and forget, threading, extensions, system.threading.tasks,async,await New In This Release: - - Improved memory management - - Implemented WeakEventManager + - Added WeakEventManager Copyright (c) 2018 Brandon Minnick diff --git a/Src/AsyncAwaitBestPractices/WeakEventManager.cs b/Src/AsyncAwaitBestPractices/WeakEventManager.cs index 71da7c1..944c96c 100644 --- a/Src/AsyncAwaitBestPractices/WeakEventManager.cs +++ b/Src/AsyncAwaitBestPractices/WeakEventManager.cs @@ -3,6 +3,7 @@ using System.Reflection; using static System.String; +using System.Runtime.CompilerServices; namespace AsyncAwaitBestPractices { @@ -17,10 +18,10 @@ public class WeakEventManager /// /// Adds the event handler /// - /// Event name /// Handler + /// Event name /// EventHandler type - public void AddEventHandler(string eventName, EventHandler handler) + public void AddEventHandler(EventHandler handler, [CallerMemberName] string eventName = "") where TEventArgs : EventArgs { if (IsNullOrWhiteSpace(eventName)) @@ -35,9 +36,9 @@ public void AddEventHandler(string eventName, EventHandler /// Adds the event handler /// - /// Event name /// Handler - public void AddEventHandler(string eventName, EventHandler handler) + /// Event name + public void AddEventHandler(EventHandler handler, [CallerMemberName] string eventName = "") { if (IsNullOrWhiteSpace(eventName)) throw new ArgumentNullException(nameof(eventName)); @@ -96,10 +97,10 @@ public void HandleEvent(object sender, object args, string eventName) /// /// Removes the event handler /// - /// Event name /// Handler + /// Event name /// EventHandler type - public void RemoveEventHandler(string eventName, EventHandler handler) + public void RemoveEventHandler(EventHandler handler, [CallerMemberName] string eventName = "") where TEventArgs : EventArgs { if (IsNullOrEmpty(eventName)) @@ -114,9 +115,9 @@ public void RemoveEventHandler(string eventName, EventHandler /// Removes the event handler. /// - /// Event name /// Handler - public void RemoveEventHandler(string eventName, EventHandler handler) + /// Event name + public void RemoveEventHandler(EventHandler handler, [CallerMemberName] string eventName = "") { if (IsNullOrEmpty(eventName)) throw new ArgumentNullException(nameof(eventName));