/// <summary> /// Invokes asynchronous event handlers, returning a task that completes when all event handlers have been invoked. /// Each handler is fully executed (including continuations) before the next handler in the list is invoked. /// </summary> /// <typeparam name="TEventArgs">The type of argument passed to each handler.</typeparam> /// <param name="handlers">The event handlers. May be <c>null</c></param> /// <param name="sender">The event source.</param> /// <param name="args">The event argument.</param> /// <returns>The task that completes when all handlers have completed. The task is faulted if any handlers throw an exception.</returns> /// <exception cref="AggregateException">Thrown if any handlers fail. It contains a collection of all failures.</exception> public static async Task InvokeAsync <TEventArgs>(this AsyncEventHandler <TEventArgs> handlers, object sender, TEventArgs args) where TEventArgs : EventArgs { if (handlers != null) { var individualHandlers = handlers.GetInvocationList(); List <Exception> exceptions = null; foreach (AsyncEventHandler <TEventArgs> handler in individualHandlers) { try { await handler(sender, args); } catch (Exception ex) { if (exceptions == null) { exceptions = new List <Exception>(2); } exceptions.Add(ex); } } if (exceptions != null) { throw new AggregateException(exceptions); } } }
public Task RaiseEventOnBackgroundAsync <TArgs>(object sender, AsyncEventHandler <TArgs> eventHandlers, TArgs args) where TArgs : EventArgs { return(_joinableTaskContext.Factory.RunAsync(async() => { await TaskScheduler.Default; if (eventHandlers == null) { return; } var handlers = eventHandlers.GetInvocationList(); foreach (AsyncEventHandler <TArgs> handler in handlers) { try { BeforeCallingEventHandler(handler); await handler(sender, args); } catch (Exception e) { HandleException(sender, e); } finally { AfterCallingEventHandler(handler); } } }).Task); }
/// <summary> /// Invokes asynchronous event handlers, returning a task that completes when all event handlers have been invoked. /// Each handler is fully executed (including continuations) before the next handler in the list is invoked. /// </summary> /// <typeparam name="TEventArgs">The type of argument passed to each handler.</typeparam> /// <param name="handlers">The event handlers. May be <c>null</c>.</param> /// <param name="sender">The event source.</param> /// <param name="args">The event argument.</param> /// <returns>The task that completes when all handlers have completed. The task is faulted if any handlers throw an exception.</returns> /// <exception cref="AggregateException">Thrown if any handlers fail. It contains a collection of all failures.</exception> public static async Task InvokeAsync <TEventArgs>(this AsyncEventHandler <TEventArgs>?handlers, object?sender, TEventArgs args) { if (handlers is object) { Delegate[]? individualHandlers = handlers.GetInvocationList(); List <Exception>?exceptions = null; foreach (AsyncEventHandler <TEventArgs> handler in individualHandlers) { try { await handler(sender, args).ConfigureAwait(true); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { if (exceptions is null) { exceptions = new List <Exception>(2); } exceptions.Add(ex); } } if (exceptions is object) { throw new AggregateException(exceptions); } } }
public Task RaiseEventOnBackgroundAsync <TArgs>(object sender, AsyncEventHandler <TArgs> eventHandlers, TArgs args) where TArgs : EventArgs { return(_joinableTaskContext.Factory.RunAsync(async() => { await TaskScheduler.Default; if (eventHandlers == null) { return; } var handlers = eventHandlers.GetInvocationList(); for (int i = 0; (i < handlers.Length); ++i) { var handler = (AsyncEventHandler <TArgs>)(handlers[i]); try { BeforeCallingEventHandler(handler); await handler(sender, args).ConfigureAwait(true); } catch (Exception e) { HandleException(sender, e); } finally { AfterCallingEventHandler(handler); } } }).Task); }
private static async Task InvokeAsync <T>(AsyncEventHandler <T>? @event, T eventArgs) { if (@event != null) { await Task.WhenAll(@event.GetInvocationList().Select(eventHandler => ((AsyncEventHandler <T>)eventHandler).Invoke(null, eventArgs))); } }
/// <summary> /// Invokes an asynchronous event. /// </summary> /// <param name="handler">The event handler.</param> /// <param name="sender">The sender.</param> /// <returns>An task that can be awaited on by the invoker.</returns> public static Task InvokeAsync( this AsyncEventHandler?handler, object sender) { _ = Requires.NotNull(sender); Delegate[]? invocationList = handler?.GetInvocationList(); return((invocationList?.Length ?? 0) switch { 0 => Task.CompletedTask, 1 => handler !.Invoke( sender, EventArgs.Empty), _ => Task.WhenAll( invocationList !.Cast <AsyncEventHandler>() .Aggregate( (Sender: sender, TaskList: new List <Task>()), ( tuple, eventHandler) => { tuple.TaskList.Add( eventHandler.Invoke( tuple.Sender, EventArgs.Empty)); return tuple; }) .TaskList) });
public static Task[] InvokeAll <TEventArgs>( this AsyncEventHandler <TEventArgs> handler, object sender, TEventArgs e) where TEventArgs : EventArgs => ( from AsyncEventHandler <TEventArgs> h in handler.GetInvocationList() select h(sender, e)).ToArray();
/// <summary> /// 调度异步事件,并返回会等待所有异步操作全部完成的操作。 /// </summary> /// <param name="handler">要调度的异步事件。</param> /// <param name="sender">事件源。</param> /// <returns>会等待所有异步操作全部完成的操作。</returns> /// <overloads> /// <summary> /// 调度异步事件,并返回会等待所有异步操作全部完成的操作。 /// </summary> /// </overloads> public static async Task OnAll(this AsyncEventHandler handler, object sender) { if (handler == null) { return; } var invocations = handler.GetInvocationList(); await Task.WhenAll(invocations.Select(invocation => ((AsyncEventHandler)invocation)(sender, EventArgs.Empty))); }
public static async Task InvokeAsync <T>(this AsyncEventHandler <T> callback, object sender, T args, ExceptionHandler exceptionFunc) { var invocationList = callback.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { await InternalInvokeAsync((AsyncEventHandler <T>) invocationList[i], sender, args, exceptionFunc); } }
/// <summary> /// 调度异步事件,并返回任意异步操作完成,就会完成的操作。 /// </summary> /// <param name="handler">要调度的异步事件。</param> /// <param name="sender">事件源。</param> /// <param name="e">一个包含事件数据的对象。</param> /// <returns>任意异步操作完成,就会完成的操作。</returns> public static async Task OnAny <TEventArgs>(this AsyncEventHandler <TEventArgs> handler, object sender, TEventArgs e) { if (handler == null) { return; } var invocations = handler.GetInvocationList(); await Task.WhenAny(invocations.Select(invocation => ((AsyncEventHandler <TEventArgs>)invocation)(sender, e))); }
public static Task RaiseAsync <T>(this AsyncEventHandler <T> eventHandler, object sender, T eventArgs) where T : EventArgs { if (eventHandler == null) { return(Task.FromResult(false)); } return(Task.WhenAll(eventHandler.GetInvocationList().Cast <AsyncEventHandler <T> >().Select(x => x.Invoke(sender, eventArgs)))); }
/// <summary> /// Asynchronously invokes an event, dispatching the provided event arguments to all registered handlers. /// </summary> /// <typeparam name="TEventArgs">The type of the event arguments.</typeparam> /// <param name="eventHandler">This event handler.</param> /// <param name="sender">The object firing the event.</param> /// <param name="eventArgs">The object containing the event data.</param> /// <returns>A task that completes only when all registered handlers complete.</returns> public static Task InvokeAsync <TEventArgs>( this AsyncEventHandler <TEventArgs> eventHandler, object sender, TEventArgs eventArgs) { var delegates = eventHandler.GetInvocationList().Cast <AsyncEventHandler <TEventArgs> >(); var tasks = delegates.Select(it => it.Invoke(sender, eventArgs)); return(Task.WhenAll(tasks)); }
public static async Task InvokeAsync <TEvent>(this AsyncEventHandler <TEvent> eventHandler, object sender, TEvent @event) where TEvent : EventArgs { if (eventHandler != null) { foreach (AsyncEventHandler <TEvent> handlerInstance in eventHandler.GetInvocationList()) { await handlerInstance(sender, @event).ConfigureAwait(false); } } }
/// <summary> /// sequentially iterates, invokes and awaits all registered AsyncEventHandlers. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="eventHandler">The EventHandler to invoke.</param> /// <param name="sender">The sender of the event.</param> /// <param name="args">The arguments.</param> /// <returns>Returns a task representing the asynchronous operation.</returns> public static async Task RaiseAsync <T>(this AsyncEventHandler <T> eventHandler, object sender, T args) { if (eventHandler != null) { foreach (var del in eventHandler.GetInvocationList().Cast <AsyncEventHandler <T> >()) { await del.Invoke(sender, args); } } }
public static async Task InvokeSerial <TEventArgs>(this AsyncEventHandler <TEventArgs> handler, object sender, TEventArgs e) { if (handler != null) { foreach (AsyncEventHandler <TEventArgs> invoke in handler.GetInvocationList()) { await invoke(sender, e); } } }
internal static async Task InvokeAsync <T>(this AsyncEventHandler <T> callback, object sender, T args, ExceptionHandler exceptionFunc) { var invocationList = callback.GetInvocationList(); foreach (var @delegate in invocationList) { await InternalInvokeAsync((AsyncEventHandler <T>) @delegate, sender, args, exceptionFunc); } }
public static IEnumerable <AsyncEventHandler <TEventArgs> > GetHandlers <TEventArgs>( this AsyncEventHandler <TEventArgs>?handler ) where TEventArgs : EventArgs { if (handler == null) { return(Enumerable.Empty <AsyncEventHandler <TEventArgs> >()); } return(handler.GetInvocationList().Cast <AsyncEventHandler <TEventArgs> >()); }
/// <summary> /// Asynchronously invokes an event, dispatching the provided event arguments to all registered handlers. /// </summary> /// <param name="eventHandler">This event handler.</param> /// <param name="sender">The object firing the event.</param> /// <param name="eventArgs">The object containing the event data.</param> /// <returns> /// A task that completes only when all registered handlers complete. A completed task is returned if the event handler is /// null. /// </returns> public static Task InvokeAsync(this AsyncEventHandler eventHandler, object sender, EventArgs eventArgs) { if (eventHandler == null) { return(Task.CompletedTask); } var delegates = eventHandler.GetInvocationList().Cast <AsyncEventHandler>(); var tasks = delegates.Select(it => it.Invoke(sender, eventArgs)); return(Task.WhenAll(tasks)); }
public static void InvokeParallel <T>(this AsyncEventHandler <T> callback, object sender, T args) { var invocationList = callback.GetInvocationList(); var handlerTasks = new Task[invocationList.Length]; for (int i = 0; i < invocationList.Length; i++) { handlerTasks[i] = ((AsyncEventHandler <T>)invocationList[i])(sender, args); } Task.WhenAll(handlerTasks).Wait(); }
private void ClearEvent(ref AsyncEventHandler sessionEvent) { if (sessionEvent == null) { return; } foreach (var handler in sessionEvent.GetInvocationList()) { sessionEvent -= (AsyncEventHandler)handler; } }
public static async Task InvokeParallelAsync <T>(this AsyncEventHandler <T> callback, object sender, T args, Action <Exception> exceptionFunc) { var invocationList = callback.GetInvocationList(); var handlerTasks = new Task[invocationList.Length]; for (int i = 0; i < invocationList.Length; i++) { handlerTasks[i] = InternalInvokeAsync((AsyncEventHandler <T>)invocationList[i], sender, args, exceptionFunc); } await Task.WhenAll(handlerTasks); }
public static Task InvokeAndWaitAsync <T>(this AsyncEventHandler <T> eventHandler, T eventArgs) { if (eventHandler == null) { return(Task.CompletedTask); } var delegates = eventHandler.GetInvocationList().Cast <AsyncEventHandler <T> >(); var tasks = delegates.Select(it => it.Invoke(eventArgs)); return(Task.WhenAll(tasks)); }
public static async Task RaiseAsync <TEventArgs>(this AsyncEventHandler <TEventArgs> handlers, object sender, TEventArgs eventArgs) where TEventArgs : EventArgs { if (handlers == null) { return; } foreach (var handler in handlers.GetInvocationList().OfType <AsyncEventHandler <TEventArgs> >()) { await handler(sender, eventArgs); } }
public static async Task InvokeAsync <TEventArgs>(this AsyncEventHandler <TEventArgs>?eventHandler, object sender, TEventArgs eventArgs) where TEventArgs : EventArgs { if (eventHandler == null) { return; } var delegateArray = eventHandler.GetInvocationList(); foreach (var t in delegateArray) { await((AsyncEventHandler <TEventArgs>)t)(sender, eventArgs).ConfigureAwait(false); } }
public static async Task InvokeAsync <TArgs>(this AsyncEventHandler <TArgs> handler, object source, TArgs args) where TArgs : EventArgs { if (handler == null) { return; } Delegate[] invocations = handler.GetInvocationList(); for (int i = 0; i < invocations.Length; i++) { await((AsyncEventHandler <TArgs>)invocations[i])(source, args).ConfigureAwait(false); } }
public void Subscribe(AsyncEventHandler <TEventArgs> handler) { var singleHandlers = handler .GetInvocationList() .Cast <AsyncEventHandler <TEventArgs> >() .ToList(); lock (_handlers) { foreach (var h in singleHandlers) { _handlers.Add(h); } } }
/// <summary> /// 在正确的线程调度当前异步事件。 /// </summary> /// <typeparam name="TEventArgs">由该事件生成的事件数据的类型。</typeparam> /// <param name="handler">要调度的异步事件。</param> /// <param name="sender">事件源。</param> /// <param name="e">不包含事件数据的对象。</param> /// <remarks>如果异步事件的接收者实现了 <see cref="ISynchronizeInvoke"/> 接口,那么会将调用封送到正确的线程。</remarks> public static void Raise <TEventArgs>(this AsyncEventHandler <TEventArgs> handler, object sender, TEventArgs e) { foreach (var dlg in handler.GetInvocationList()) { var target = dlg.Target as ISynchronizeInvoke; if (target != null) { target.BeginInvoke(dlg, new[] { sender, e }); } else { ((AsyncEventHandler <TEventArgs>)dlg)(sender, e); } } }
public static Task InvokeAsync <T>(this AsyncEventHandler <T>?ev, object?sender, T value) { if (ev == null) { return(Task.CompletedTask); } var invList = ev.GetInvocationList(); if (invList.Length == 1) { return(((AsyncEventHandler <T>)invList[0]).Invoke(sender, value)); } return(Task.WhenAll(invList.Select(func => ((AsyncEventHandler <T>)func).Invoke(sender, value)))); }
public void Unsubscribe(AsyncEventHandler <TEventArgs> handler) { var singleHandlers = handler .GetInvocationList() .Cast <AsyncEventHandler <TEventArgs> >(); lock (_handlers) { foreach (var singleHandler in singleHandlers) { _handlers.Remove(singleHandler); } _handlers.CollectDeleted(); } }
/// <summary> /// Invokes asynchronous event handlers, returning a task that completes /// when all event handlers have been invoked sequentially: /// Each handler is fully executed (including continuations) /// before the next handler in the list is invoked. /// </summary> /// <param name="handler">The delegate to invoke.</param> /// <param name="sender">The event sender</param> /// <param name="args">The event data</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>A task that signals completion of the operation.</returns> public static async Task InvokeAsync(this AsyncEventHandler handler, object sender, EventArgs args, CancellationToken cancellationToken = default) { if (handler == null) { return; } var delegates = handler .GetInvocationList() .Cast <AsyncEventHandler>(); foreach (var @delegate in delegates) { cancellationToken.ThrowIfCancellationRequested(); await @delegate(sender, args, cancellationToken); } }