Exemple #1
0
        /// <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);
                }
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #5
0
 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();
Exemple #8
0
 /// <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)));
 }
Exemple #9
0
        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);
            }
        }
Exemple #10
0
 /// <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));
        }
Exemple #13
0
 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);
         }
     }
 }
Exemple #14
0
 /// <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);
         }
     }
 }
Exemple #15
0
 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);
         }
     }
 }
Exemple #16
0
        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);
            }
        }
Exemple #17
0
    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();
        }
Exemple #20
0
        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);
        }
Exemple #22
0
        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));
        }
Exemple #23
0
    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);
        }
    }
Exemple #24
0
        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);
                }
            }
        }
Exemple #27
0
 /// <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);
         }
     }
 }
Exemple #28
0
        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();
            }
        }
Exemple #30
0
        /// <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);
            }
        }