public async Task Exception_Is_Not_Swallowed_If_ExceptionHandler_Returns_False() { var source = new AsyncWeakEventSource <EventArgs>(); bool throwingHandlerCalled = false; bool nonThrowingHandlerCalled = false; source.Subscribe(ThrowingHandler); source.Subscribe(NonThrowingHandler); Func <Task> raise = () => source.RaiseAsync(this, EventArgs.Empty, ExceptionHandler); await raise.Should().ThrowAsync <Exception>().WithMessage("Oops"); throwingHandlerCalled.Should().BeTrue(); nonThrowingHandlerCalled.Should().BeFalse(); async Task ThrowingHandler(object sender, EventArgs e) { await Task.Yield(); throwingHandlerCalled = true; throw new Exception("Oops"); } async Task NonThrowingHandler(object sender, EventArgs e) { await Task.Yield(); nonThrowingHandlerCalled = true; }
public void Handler_List_Is_Compacted_Even_If_Raise_Or_Unsubscribe_Isnt_Called() { var source = new AsyncWeakEventSource <EventArgs>(); // Add many handlers (more than 50) for (int i = 0; i < 120; i++) { source.Subscribe(new InstanceSubscriber(i, _ => Task.CompletedTask).OnFoo); // Run GC every now and then if (i % 25 is 0) { GC.Collect(); } } source._handlers?.Count.Should().BeLessThan(50); }
public async Task Subscriber_Dies_If_Lifetime_Object_Is_Dead() { bool handlerWasCalled = false; var source = new AsyncWeakEventSource <EventArgs>(); object?lifetime = new object(); source.Subscribe(lifetime, new InstanceSubscriber(1, async i => { handlerWasCalled = true; await Task.Yield(); }).OnFoo); lifetime = null; GC.Collect(); GC.WaitForPendingFinalizers(); await source.RaiseAsync(this, EventArgs.Empty); handlerWasCalled.Should().BeFalse(); }
public Disposable(AsyncWeakEventSource <TEvent> eventSource, AsyncEventHandler <TEvent> handler) { _eventSource = eventSource; _handler = handler; }