|
| 1 | +using System; |
1 | 2 | using System.Threading.Tasks; |
2 | 3 | using static WeakEvent.WeakEventSourceHelper; |
3 | 4 |
|
4 | 5 | namespace WeakEvent |
5 | 6 | { |
| 7 | + /// <summary> |
| 8 | + /// Represents the method that will handle an event asynchronously when the event provides data. |
| 9 | + /// </summary> |
| 10 | + /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam> |
| 11 | + /// <param name="sender">The source of the event.</param> |
| 12 | + /// <param name="e">An object that contains the event data.</param> |
| 13 | + /// <returns></returns> |
6 | 14 | public delegate Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e); |
7 | | - |
| 15 | + |
| 16 | + /// <summary> |
| 17 | + /// An async event with weak subscription, i.e. it won't keep handlers from being garbage collected. |
| 18 | + /// </summary> |
| 19 | + /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam> |
8 | 20 | public class AsyncWeakEventSource<TEventArgs> |
9 | 21 | { |
10 | 22 | private DelegateCollection? _handlers; |
11 | 23 |
|
12 | | - public async Task RaiseAsync(object? sender, TEventArgs e) |
| 24 | + /// <summary> |
| 25 | + /// Raises the event by invoking each handler that hasn't been garbage collected. |
| 26 | + /// </summary> |
| 27 | + /// <param name="sender">The source of the event.</param> |
| 28 | + /// <param name="args">An object that contains the event data.</param> |
| 29 | + /// <remarks>The handlers are invoked one after the other, in the order they were subscribed in. |
| 30 | + /// Each handler is awaited before invoking the next one.</remarks> |
| 31 | + public async Task RaiseAsync(object? sender, TEventArgs args) |
13 | 32 | { |
14 | 33 | var validHandlers = GetValidHandlers(_handlers); |
15 | 34 | foreach (var handler in validHandlers) |
16 | 35 | { |
17 | | - await handler.Invoke(sender, e); |
| 36 | + await handler.Invoke(sender, args); |
18 | 37 | } |
19 | 38 | } |
20 | 39 |
|
| 40 | + /// <summary> |
| 41 | + /// Adds an event handler. |
| 42 | + /// </summary> |
| 43 | + /// <param name="handler">The handler to subscribe.</param> |
| 44 | + /// <remarks>Only a weak reference to the handler's <c>Target</c> is kept, so that it can be garbage collected.</remarks> |
21 | 45 | public void Subscribe(AsyncEventHandler<TEventArgs> handler) |
22 | 46 | { |
23 | 47 | Subscribe(null, handler); |
24 | 48 | } |
25 | 49 |
|
| 50 | + /// <summary> |
| 51 | + /// Adds an event handler, specifying a lifetime object. |
| 52 | + /// </summary> |
| 53 | + /// <param name="lifetimeObject">An object that keeps the handler alive as long as it's alive.</param> |
| 54 | + /// <param name="handler">The handler to subscribe.</param> |
| 55 | + /// <remarks>Only a weak reference to the handler's <c>Target</c> is kept, so that it can be garbage collected. |
| 56 | + /// However, as long as the <c>lifetime</c> object is alive, the handler will be kept alive. This is useful for |
| 57 | + /// subscribing with anonymous methods (e.g. lambda expressions). Note that you must specify the same lifetime |
| 58 | + /// object to unsubscribe, otherwise the handler's lifetime will remain tied to the lifetime object.</remarks> |
26 | 59 | public void Subscribe(object? lifetimeObject, AsyncEventHandler<TEventArgs> handler) |
27 | 60 | { |
28 | 61 | Subscribe<DelegateCollection, OpenEventHandler, StrongHandler>(lifetimeObject, ref _handlers, handler); |
29 | 62 | } |
30 | 63 |
|
| 64 | + /// <summary> |
| 65 | + /// Removes an event handler. |
| 66 | + /// </summary> |
| 67 | + /// <param name="handler">The handler to unsubscribe.</param> |
| 68 | + /// <remarks>The behavior is the same as that of <see cref="Delegate.Remove(Delegate, Delegate)"/>. Only the last instance |
| 69 | + /// of the handler's invocation list is removed. If the exact invocation list is not found, nothing is removed.</remarks> |
31 | 70 | public void Unsubscribe(AsyncEventHandler<TEventArgs> handler) |
32 | 71 | { |
33 | 72 | Unsubscribe(null, handler); |
34 | 73 | } |
35 | 74 |
|
| 75 | + /// <summary> |
| 76 | + /// Removes an event handler that was subscribed with a lifetime object. |
| 77 | + /// </summary> |
| 78 | + /// <param name="lifetimeObject">The lifetime object that was associated with the handler.</param> |
| 79 | + /// <param name="handler">The handler to unsubscribe.</param> |
| 80 | + /// <remarks>The behavior is the same as that of <see cref="Delegate.Remove(Delegate, Delegate)"/>. Only the last instance |
| 81 | + /// of the handler's invocation list is removed. If the exact invocation list is not found, nothing is removed.</remarks> |
36 | 82 | public void Unsubscribe(object? lifetimeObject, AsyncEventHandler<TEventArgs> handler) |
37 | 83 | { |
38 | 84 | Unsubscribe<OpenEventHandler, StrongHandler>(lifetimeObject, _handlers, handler); |
|
0 commit comments