public static async Task NullableInvokeAsync <T>(this AsyncEvent <T> asyncEvent, object sender, T eventArgs) { if (asyncEvent != null) { await asyncEvent.InvokeAsync(sender, eventArgs); } }
public async Task <T> Await(CancellationToken cancellationToken) { try { await _completionSource.Task .WithCancellation(cancellationToken) .ConfigureAwait(false); } finally { _asyncEvent -= SubscriptionHandler; } return(_completionSource.Task.Result); }
public static AsyncEvent <TEventArgs> operator +( AsyncEvent <TEventArgs> e, Func <object, TEventArgs, Task> callback) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } //Note: Thread safety issue- if two threads register to the same event (on the first time, i.e when it is null) //they could get a different instance, so whoever was first will be overridden. //A solution for that would be to switch to a public constructor and use it, but then we'll 'lose' the similar syntax to c# events if (e == null) { e = new AsyncEvent <TEventArgs>(); } lock (e._locker) { e._invocationList.Add(callback); } return(e); }
public AsyncEventAwaiter(ref AsyncEvent <T> asyncEvent) { asyncEvent += SubscriptionHandler; _asyncEvent = asyncEvent; _completionSource = new TaskCompletionSource <T>(); }