Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InvalidOperationException when triggering an event at the same time an event handler is unregistered #6726

Closed
HenriqueHilleshein opened this issue May 30, 2023 · 0 comments · Fixed by #6805
Assignees
Milestone

Comments

@HenriqueHilleshein
Copy link

I have an issue that if an event handler is unregistered while an event is being handled, the InvalidOperationException exception is thrown:

<System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at Abp.Events.Bus.EventBus.TriggerAsync(Type eventType, Object eventSource, IEventData eventData)
   at EventBusTest.Tests.EventBusTest.<>c__DisplayClass2_0.<<EventBustTest_UnregisterWhileHandlingEvent_ShouldNotThrow>b__1>d.MoveNext() in C:\Users\henrique.hilleshein\source\repos\Prime_LAS\LAM\aspnet-core\test\LAM.Tests\EventBusTest.cs:line 44
--- End of stack trace from previous location ---
   at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.GetResult()
   at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(Func`1 invoke)
   at NUnit.Framework.Internal.ExceptionHelper.RecordException(Delegate parameterlessDelegate, String parameterName)>

In short, I would expect this to not happen. The unit test below represents what I would expect to happen:

using System;
using System.Threading;
using System.Threading.Tasks;
using Abp.Events.Bus;
using NUnit.Framework;

namespace EventBusTest.Tests
{
    internal class MyEvent : EventData
    {
        public SemaphoreSlim Semaphore { get; set; }

        public MyEvent() 
        {
            Semaphore = new SemaphoreSlim(0);
        }
    }

    internal class EventBusTest
    {
        IEventBus eventBus;

        [SetUp]
        public void Setup()
        {
            eventBus = new EventBus();
        }

        [Test, Timeout(3000)]
        public void EventBustTest_UnregisterWhileHandlingEvent_ShouldNotThrow()
        {
            // Arrange
            Func<MyEvent, Task> eventHandler = async (myEvent) => await myEvent.Semaphore.WaitAsync();
            eventBus.AsyncRegister(eventHandler);
            var myEvent = new MyEvent();

            // Act
            var triggerTask = eventBus.TriggerAsync(myEvent);
            eventBus.AsyncUnregister(eventHandler);
            myEvent.Semaphore.Release();

            // Assert
            Assert.DoesNotThrowAsync(async () => await triggerTask);
        }
    }
}

My Framework is .Net Core and my Abp version is 7.4.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants