/// <summary> /// Awaits the closing of a the <see cref="ViewModelBase" />. This method should be used with care, and can hook into /// an existing close operation called on the <see cref="ViewModelBase" />. /// </summary> /// <param name="viewModel">The view model.</param> /// <param name="timeout">The timeout.</param> public static async Task AwaitClosingAsync(this ViewModelBase viewModel, int timeout = 50) { // We should somehow have the task here to await, but we don't want to add a `ClosingTask` // on the vm, so we will listen to events // // To "solve" this, we'll give the VM only 50ms to save itself, which is extremely reasonable var tcs = new TaskCompletionSource <object>(); var closedHandler = new AsyncEventHandler <ViewModelClosedEventArgs>(async(sender, e) => { tcs.TrySetResult(true); }); viewModel.ClosedAsync += closedHandler; try { await tcs.Task.AwaitWithTimeoutAsync(timeout); } catch (Exception ex) { Log.Error(ex, $"Failed to await closing of view model '{viewModel.UniqueIdentifier}'"); throw; } finally { viewModel.ClosedAsync -= closedHandler; } }
private void Init(IFrameHandler fh) { m_delegate = new Connection(m_factory, false, fh, this.ClientProvidedName); AutorecoveringConnection self = this; AsyncEventHandler <ShutdownEventArgs> recoveryListener = (_, args) => { if (ShouldTriggerConnectionRecovery(args)) { try { self.BeginAutomaticRecovery(); } catch (Exception e) { ESLog.Error("BeginAutomaticRecovery() failed.", e); } } return(Task.CompletedTask); }; lock (m_eventLock) { ConnectionShutdown += recoveryListener; if (!m_recordedShutdownEventHandlers.Contains(recoveryListener)) { m_recordedShutdownEventHandlers.Add(recoveryListener); } } }
public void Subscribe(string eventName, AsyncEventHandler <PlayerRemoteEventEventArgs> callback) { if (_subscriptions.TryGetValue(eventName, out var eventSubscriptions) == false) { eventSubscriptions = new HashSet <AsyncEventHandler <PlayerRemoteEventEventArgs> >(); if (_subscriptions.TryAdd(eventName, eventSubscriptions) == false) { _plugin.Logger.Error($"Unable to create subscription list for event {eventName}"); return; } NativePlayerRemoteEventDelegate data = (playerPointer, arguments) => OnPlayerRemoteEvent(playerPointer, eventName, arguments); GCHandle.Alloc(data); using (var converter = new StringConverter()) { Rage.Multiplayer.Multiplayer_AddRemoteEventHandler(_plugin.NativeMultiplayer, converter.StringToPointer(eventName), data); } } eventSubscriptions.Add(callback); }
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 async Task PacketReceiveHandler(AsyncEventHandler <BasicDeliverEventArgs> callback, object sender, BasicDeliverEventArgs eventArgs) { try { await callback(sender, eventArgs); Channel.BasicAck(eventArgs.DeliveryTag, false); } catch (Exception ex) { int count = 0; if (eventArgs.BasicProperties.Headers == null) { eventArgs.BasicProperties.Headers = new Dictionary <string, object>(); } if (eventArgs.BasicProperties.Headers.ContainsKey("x-redelivered-count")) { count = (int)eventArgs.BasicProperties.Headers["x-redelivered-count"]; } else { eventArgs.BasicProperties.Headers.Add("x-redelivered-count", 0); } count++; eventArgs.BasicProperties.Headers["x-redelivered-count"] = count; Channel.BasicNack(eventArgs.DeliveryTag, false, count > 0); //Logger.Write($"RabbitMQ Consume Catch::{ex.Message}", System.Diagnostics.TraceEventType.Error.ToString()); } }
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> /// Sequentially invokes asyncrounous multicast delegate. /// </summary> /// <param name="handler">Multicast delegate to invoke.</param> /// <param name="sender">Sender object.</param> /// <param name="e"> /// Instance of <see cref="T:NCoreUtils.Async.AsyncEventArgs" /> handling the cancellation. /// </param> /// <returns> /// Task which is completed when all callbacks has been processed. /// </returns> public static async Task InvokeAsync <T>(this AsyncEventHandler <T> handler, object sender, T e) where T : AsyncEventArgs { foreach (var item in AsyncDelegateExtensions.EnumerateInvokationList(handler, e.CancellationToken).Cast <AsyncEventHandler <T> >()) { await item.Invoke(sender, e); } }
public async Task <MessageContext> WaitForMessageAsync(Func <DiscordMessage, bool> predicate, TimeSpan timeout) { var tsc = new TaskCompletionSource <MessageContext>(); var ct = new CancellationTokenSource(timeout); ct.Token.Register(() => tsc.TrySetResult(null)); AsyncEventHandler <MessageCreateEventArgs> handler = async(e) => { await Task.Yield(); if (predicate(e.Message)) { var mc = new MessageContext() { Interactivity = this, Message = e.Message }; tsc.TrySetResult(mc); return; } }; this.Client.MessageCreated += handler; var result = await tsc.Task; this.Client.MessageCreated -= handler; return(result); }
public async Task <TypingContext> WaitForTypingChannelAsync(DiscordUser user, TimeSpan timeout) { var user_id = user.Id; var tsc = new TaskCompletionSource <TypingContext>(); var ct = new CancellationTokenSource(timeout); ct.Token.Register(() => tsc.TrySetResult(null)); AsyncEventHandler <TypingStartEventArgs> handler = async(e) => { await Task.Yield(); if (e.User.Id == user_id) { var tc = new TypingContext() { Channel = e.Channel, Interactivity = this, StartedAt = e.StartedAt, User = e.User }; tsc.TrySetResult(tc); return; } }; this.Client.TypingStarted += handler; var result = await tsc.Task; this.Client.TypingStarted -= handler; return(result); }
public async Task <ReactionCollectionContext> CreatePollAsync(DiscordMessage m, TimeSpan timeout, List <DiscordEmoji> Emojis) { foreach (var em in Emojis) { await m.CreateReactionAsync(em); } var rcc = new ReactionCollectionContext(); var tsc = new TaskCompletionSource <ReactionCollectionContext>(); var ct = new CancellationTokenSource(timeout); ct.Token.Register(() => tsc.TrySetResult(rcc)); AsyncEventHandler <MessageReactionAddEventArgs> handler1 = async(e) => { await Task.Yield(); if (e.Message.Id == m.Id && Emojis.Count(x => x == e.Emoji) > 0) { rcc.AddReaction(e.Emoji, e.User.Id); } }; this.Client.MessageReactionAdded += handler1; AsyncEventHandler <MessageReactionRemoveEventArgs> handler2 = async(e) => { await Task.Yield(); if (e.Message.Id == m.Id && Emojis.Count(x => x == e.Emoji) > 0) { rcc.RemoveReaction(e.Emoji, e.User.Id); } }; this.Client.MessageReactionRemoved += handler2; AsyncEventHandler <MessageReactionsClearEventArgs> handler3 = async(e) => { await Task.Yield(); if (e.Message.Id == m.Id) { rcc.ClearReactions(); foreach (var em in Emojis) { await m.CreateReactionAsync(em); } } }; this.Client.MessageReactionsCleared += handler3; var result = await tsc.Task; this.Client.MessageReactionAdded -= handler1; this.Client.MessageReactionRemoved -= handler2; this.Client.MessageReactionsCleared -= handler3; return(result); }
/// <summary> /// 异步调用事件 /// </summary> /// <param name="handlers">事件处理器</param> /// <param name="session">会话</param> /// <param name="e">事件数据</param> private static async Task InvokeAsync(AsyncEventHandler <TEventArgs> handlers, Session session, TEventArgs e) { if (handlers != null) { await handlers.Invoke(session, e); } }
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); }
public async Task MixedEventsInFeed() { var mock = new Mock <IEventFeed <AsyncEventHandler <Handler, TestEv> > >(); IEnumerable <SubscribedDomainEventWrapper> list = new [] { new SubscribedDomainEventWrapper { DomainEvent = new TestEv(Guid.NewGuid()) }, new SubscribedDomainEventWrapper { DomainEvent = new TestEv2(Guid.NewGuid()) } }; mock.Setup(feed => feed.GetEventsAsync(It.IsAny <long>())).ReturnsAsync(list); var versionRepo = new Mock <IVersionRepository>(); versionRepo.Setup(repo => repo.SaveVersion(It.IsAny <LastProcessedVersion>())).Returns(Task.CompletedTask); versionRepo.Setup(repo => repo.GetVersionAsync(It.IsAny <string>())).ReturnsAsync(0); var handler = new Handler(); var eventDelegateHandler = new AsyncEventHandler <Handler, TestEv>(versionRepo.Object, mock.Object, handler); await eventDelegateHandler.UpdateAsync(); Assert.AreEqual(1, handler.WasCalled); }
protected virtual async Task WithSubTask(IReportsProgress task, Func <Task> func) { var nameChanged = new AsyncEventHandler(async(sender, e) => { using (e.Defer()) await this.SetName(task.Name).ConfigureAwait(false); }); var descriptionChanged = new AsyncEventHandler(async(sender, e) => { using (e.Defer()) await this.SetDescription(task.Description).ConfigureAwait(false); }); var positionChanged = new AsyncEventHandler(async(sender, e) => { using (e.Defer()) await this.SetPosition(task.Position).ConfigureAwait(false); }); var countChanged = new AsyncEventHandler(async(sender, e) => { using (e.Defer()) await this.SetCount(task.Count).ConfigureAwait(false); }); var isIndeterminateChanged = new AsyncEventHandler(async(sender, e) => { using (e.Defer()) await this.SetIsIndeterminate(task.IsIndeterminate).ConfigureAwait(false); }); task.NameChanged += nameChanged; task.DescriptionChanged += descriptionChanged; task.PositionChanged += positionChanged; task.CountChanged += countChanged; task.IsIndeterminateChanged += isIndeterminateChanged; try { await func().ConfigureAwait(false); } finally { task.NameChanged -= nameChanged; task.DescriptionChanged -= descriptionChanged; task.PositionChanged -= positionChanged; task.CountChanged -= countChanged; task.IsIndeterminateChanged -= isIndeterminateChanged; } }
static void Main(string[] args) { var c = new Program(); Console.WriteLine("ready"); var start = DateTime.Now.Ticks; //实例委托 var asy = new AsyncEventHandler(c.Event1); //异步调用开始,没有回调函数和AsyncState,都为null var ia = asy.BeginInvoke(null, null); //同步开始, c.Event2(); //异步结束,若没有结束,一直阻塞到调用完成,在此返回该函数的return,若有返回值。 asy.EndInvoke(ia); //都同步的情况。 //c.Event1(); //c.Event2(); var end = DateTime.Now.Ticks; Console.WriteLine("时间刻度差=" + Convert.ToString(end - start)); Console.ReadLine(); }
private Task <ReceivedMessage> ReceiveAsync(AsyncEventingBasicConsumer consumer) { var tcs = new TaskCompletionSource <ReceivedMessage>(); AsyncEventHandler <BasicDeliverEventArgs> handler = null; handler += (sender, args) => { try { var eventName = args.RoutingKey; var eventData = Encoding.UTF8.GetString(args.Body); var message = new ReceivedMessage(args); _logger.LogInformation($"Received message. Type: '{eventName}' | Size: '{args.Body.Length}' bytes | Data: '{eventData}'"); tcs.SetResult(message); return(Task.CompletedTask); } finally { consumer.Received -= handler; } }; consumer.Received += handler; return(tcs.Task); }
public void InvokeAsyncOfTAggregatesExceptions() { AsyncEventHandler <EventArgs> handlers = null; handlers += (sender, args) => { throw new ApplicationException("a"); }; handlers += async(sender, args) => { await Task.Yield(); throw new ApplicationException("b"); }; var task = handlers.InvokeAsync(null, null); try { task.GetAwaiter().GetResult(); Assert.True(false, "Expected AggregateException not thrown."); } catch (AggregateException ex) { Assert.Equal(2, ex.InnerExceptions.Count); Assert.Equal("a", ex.InnerExceptions[0].Message); Assert.Equal("b", ex.InnerExceptions[1].Message); } }
/// <summary> /// Creates a new Eventwaiter object. /// </summary> /// <param name="client">Your DiscordClient</param> public ReactionCollector(DiscordClient client) { this._client = client; var tinfo = this._client.GetType().GetTypeInfo(); this._requests = new ConcurrentHashSet <ReactionCollectRequest>(); // Grabbing all three events from client var handler = tinfo.DeclaredFields.First(x => x.FieldType == typeof(AsyncEvent <DiscordClient, MessageReactionAddEventArgs>)); this._reactionAddEvent = (AsyncEvent <DiscordClient, MessageReactionAddEventArgs>)handler.GetValue(this._client); this._reactionAddHandler = new AsyncEventHandler <DiscordClient, MessageReactionAddEventArgs>(this.HandleReactionAdd); this._reactionAddEvent.Register(this._reactionAddHandler); handler = tinfo.DeclaredFields.First(x => x.FieldType == typeof(AsyncEvent <DiscordClient, MessageReactionRemoveEventArgs>)); this._reactionRemoveEvent = (AsyncEvent <DiscordClient, MessageReactionRemoveEventArgs>)handler.GetValue(this._client); this._reactionRemoveHandler = new AsyncEventHandler <DiscordClient, MessageReactionRemoveEventArgs>(this.HandleReactionRemove); this._reactionRemoveEvent.Register(this._reactionRemoveHandler); handler = tinfo.DeclaredFields.First(x => x.FieldType == typeof(AsyncEvent <DiscordClient, MessageReactionsClearEventArgs>)); this._reactionClearEvent = (AsyncEvent <DiscordClient, MessageReactionsClearEventArgs>)handler.GetValue(this._client); this._reactionClearHandler = new AsyncEventHandler <DiscordClient, MessageReactionsClearEventArgs>(this.HandleReactionClear); this._reactionClearEvent.Register(this._reactionClearHandler); }
public void Add(AsyncEventHandler <TEventArgs> singleHandler) { _delegates.Add(new WeakDelegate(singleHandler)); var index = _delegates.Count - 1; AddToIndex(singleHandler, index); }
public void InvokeAsyncOfTNullEverything() { AsyncEventHandler <EventArgs> handler = null; var task = handler.InvokeAsync(null, null); Assert.True(task.IsCompleted); }
internal void Remove(AsyncEventHandler <TEventArgs> singleHandler) { var hashCode = WeakDelegate.GetHashCode(singleHandler); if (!_index.ContainsKey(hashCode)) { return; } var indices = _index[hashCode]; for (int i = indices.Count - 1; i >= 0; i--) { int index = indices[i]; if (_delegates[index] != null && _delegates[index].IsMatch(singleHandler)) { _delegates[index] = null; _deletedCount++; indices.Remove(i); } } if (indices.Count == 0) { _index.Remove(hashCode); } }
public async Task HandleIsOnlyCalledOnce() { var dateTimeOffset = 1; var domainEventWrapper = new SubscribedDomainEventWrapper { OverallVersion = dateTimeOffset, DomainEvent = new TestEv2(Guid.NewGuid()) }; var handleAsync = new Handler1(); var handleAsync2 = new Handler2(); var eventDelegateHandler1 = new AsyncEventHandler <Handler1, TestEv2>( new VersionRepositoryMongoDb(EventMongoDb), new EventFeedMock(dateTimeOffset, domainEventWrapper), handleAsync); var eventDelegateHandler2 = new AsyncEventHandler <Handler1, TestEv2>( new VersionRepositoryMongoDb(EventMongoDb), new EventFeedMock(dateTimeOffset, domainEventWrapper), handleAsync2); await eventDelegateHandler1.UpdateAsync(); await eventDelegateHandler2.UpdateAsync(); Assert.AreEqual(1, handleAsync.TimesCalled); Assert.AreEqual(1, handleAsync2.TimesCalled); }
/// <summary> /// Queues an AsyncEventHandler invocation to the SequenceTokenWorkDispatcher. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="eventHandler">The event handler.</param> /// <param name="sender">The sender.</param> /// <param name="args">The arguments.</param> /// <param name="dispatcher">The dispatcher.</param> /// <param name="tokens">The tokens.</param> public static void RaiseQueued <T>(this AsyncEventHandler <T> eventHandler, object sender, T args, SequenceTaskScheduler dispatcher, params object[] tokens) { // queue a task that produces a var task = new Task <Task>(async() => { await eventHandler.RaiseAsync(sender, args); }); dispatcher.EnqueueWorkAsync(task, tokens).ObserveExceptions(); }
public async Task <ReactionContext> WaitForReactionAsync(Func <DiscordEmoji, bool> predicate, TimeSpan timeout) { var tsc = new TaskCompletionSource <ReactionContext>(); var ct = new CancellationTokenSource(timeout); ct.Token.Register(() => tsc.TrySetResult(null)); AsyncEventHandler <MessageReactionAddEventArgs> handler = async e => { await Task.Yield(); if (predicate(e.Emoji)) { var rc = new ReactionContext() { Channel = e.Channel, Emoji = e.Emoji, Message = e.Message, User = e.User, Interactivity = this }; tsc.TrySetResult(rc); return; } }; this.Client.MessageReactionAdded += handler; var result = await tsc.Task; this.Client.MessageReactionAdded -= handler; return(result); }
///<summary>Broadcasts notification of the final shutdown of the connection.</summary> public async Task OnShutdown() { AsyncEventHandler <ShutdownEventArgs> handler; ShutdownEventArgs reason; lock (m_eventLock) { handler = m_connectionShutdown; reason = m_closeReason; m_connectionShutdown = null; } if (handler != null) { foreach (AsyncEventHandler <ShutdownEventArgs> h in handler.GetInvocationList()) { try { await h(this, reason); } catch (Exception e) { await OnCallbackException(CallbackExceptionEventArgs.Build(e, new Dictionary <string, object> { { "context", "OnShutdown" } })); } } } }
/// <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); } } }
/// <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 PropertyMetadata(DependencyProperty.UnsetValueType unsetValue, AsyncEventHandler <PropertyChangedEventArgs <T> > propertyChangedHandler = null) { _defaultValueSet = false; if (propertyChangedHandler != null) { PropertyChanged += propertyChangedHandler; } }
public static int GetHashCode(AsyncEventHandler <TEventArgs> handler) { var hashCode = -335093136; hashCode = hashCode * -1521134295 + (handler?.Target?.GetHashCode()).GetValueOrDefault(); hashCode = hashCode * -1521134295 + (handler?.GetMethodInfo()?.GetHashCode()).GetValueOrDefault(); return(hashCode); }
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> /// Initializes a new instance of the <see cref="PoolHandler"/> class. /// </summary> /// <param name="queueManager">The queue manager.</param> /// <param name="handler">The handler.</param> /// <param name="errorHandler">The error handler.</param> public PoolHandler(QueueManager queueManager, AsyncEventHandler handler, ErrorHandler errorHandler) { _queueManager = queueManager; _executionEngine = new ThreadPoolQueueExecutionEngine(_queueManager.Configuration); _executionEngine.OnThreadUsageChanged += (EventHandler) ((sender, args) => _queueManager.Counters.ThreadsInUse = (long) _executionEngine.ThreadsInUse); _handler = handler; _errorHandler = errorHandler; }
/// <summary> /// Registers the event handler. /// </summary> /// <param name="handler">The handler.</param> public void RegisterEventHandler(AsyncEventHandler handler) { AsyncServiceException.ThrowIfNull(handler, "handler"); var poolHandler = new PoolHandler(this, handler, _errorHandler); _handler = poolHandler.EventHandler; _startThreadHandler = poolHandler.StartThread; }