コード例 #1
0
        public async Task AsyncExecutionEvent_CanDisposeFromCallback_Async()
        {
            var executionEvent = new AsyncExecutionEvent <object, object>();

            int value = 0;

            Task callbackAsync(object sender, object arg)
            {
                value++;

                // Try to unregister itself.
                executionEvent.Unregister(callbackAsync);
                executionEvent.Dispose();

                return(Task.CompletedTask);
            }

            executionEvent.Register(callbackAsync);

            // Execution should increment the value and unregister the callbacks and dispose the execution event.
            await executionEvent.ExecuteCallbacksAsync(null, null);

            Assert.Equal(1, value);

            // After a while, no more executions are not possible because the event's lock is disposed.
            await Task.Delay(100);

            await Assert.ThrowsAsync <ObjectDisposedException>(async() => await executionEvent.ExecuteCallbacksAsync(null, null));

            // Further attempts to dispose execution event won't do any harm.
            executionEvent.Dispose();
        }
コード例 #2
0
        public async Task AsyncExecutionEvent_OnlyRegisteredCallbackIsCalled_Async()
        {
            using (var executionEvent = new AsyncExecutionEvent <int, int>())
            {
                int  value       = 1;
                bool called      = false;
                int  senderValue = 2;

                AsyncExecutionEventCallback <int, int> callbackAsync = (sender, arg) =>
                {
                    called = true;
                    Assert.Equal(value, arg);
                    Assert.Equal(senderValue, sender);
                    return(Task.CompletedTask);
                };
                executionEvent.Register(callbackAsync);

                await executionEvent.ExecuteCallbacksAsync(senderValue, value);

                Assert.True(called);

                // Now unregister callback and check that it won't be called anymore.
                called = false;
                executionEvent.Unregister(callbackAsync);
                await executionEvent.ExecuteCallbacksAsync(senderValue + 1, value + 1);

                Assert.False(called);
            }
        }
コード例 #3
0
        public async Task AsyncExecutionEvent_MultipleCallbacksExecutedInCorrectOrder_Async()
        {
            using (var executionEvent = new AsyncExecutionEvent <object, object>())
            {
                int orderIndex = 0;
                var orderList  = new List <int>();

                AsyncExecutionEventCallback <object, object> callback1Async = (sender, arg) =>
                {
                    orderIndex++;
                    orderList.Add(orderIndex);
                    return(Task.CompletedTask);
                };

                AsyncExecutionEventCallback <object, object> callback2Async = (sender, arg) =>
                {
                    orderIndex *= 3;
                    orderList.Add(orderIndex);
                    return(Task.CompletedTask);
                };

                AsyncExecutionEventCallback <object, object> callback3Async = (sender, arg) =>
                {
                    orderIndex = (orderIndex + 2) * 2;
                    orderList.Add(orderIndex);
                    return(Task.CompletedTask);
                };

                // We register the callbacks so that they should execute in order 1, 2, 3.
                executionEvent.Register(callback2Async);
                executionEvent.Register(callback1Async, true);
                executionEvent.Register(callback3Async);

                // We execute the callbacks and remove some of them and execute again.
                await executionEvent.ExecuteCallbacksAsync(null, null);

                executionEvent.Unregister(callback1Async);
                executionEvent.Unregister(callback3Async);

                await executionEvent.ExecuteCallbacksAsync(null, null);

                // So the final execution sequence should have been 1, 2, 3, 2, we check that.
                Assert.Equal(1, orderList[0]);  // 0 + 1 = 1
                Assert.Equal(3, orderList[1]);  // 1 * 3 = 3
                Assert.Equal(10, orderList[2]); // (3 + 2) * 2 = 10
                Assert.Equal(30, orderList[3]); // 10 * 3 = 30
                Assert.Equal(30, orderIndex);

                // After we unregister all callbacks, execution should not change the value of orderIndex.
                executionEvent.Unregister(callback2Async);
                await executionEvent.ExecuteCallbacksAsync(null, null);

                Assert.Equal(30, orderIndex);
            }
        }
コード例 #4
0
        public async Task AsyncExecutionEvent_CanUnregisterFromCallback_Async()
        {
            using (var executionEvent = new AsyncExecutionEvent <object, object>())
            {
                int value = 0;
                Task callback1Async(object sender, object arg)
                {
                    value++;

                    // Try to unregister itself.
                    executionEvent.Unregister(callback1Async);
                    return(Task.CompletedTask);
                }

                async Task callback2Async(object sender, object arg)
                {
                    value++;

                    // Try to unregister itself, but first await a bit.
                    await Task.Delay(20);

                    executionEvent.Unregister(callback2Async);
                }

                executionEvent.Register(callback1Async);
                executionEvent.Register(callback2Async);

                // First execution should increment the value twice and unregister the callbacks.
                await executionEvent.ExecuteCallbacksAsync(null, null);

                Assert.Equal(2, value);

                // Second execution should do nothing as there should be no registered callbacks.
                await executionEvent.ExecuteCallbacksAsync(null, null);

                Assert.Equal(2, value);
            }
        }
コード例 #5
0
        public void AsyncExecutionEvent_UnregisterGuarantee()
        {
            var rnd = new Random();

            using (var executionEvent = new AsyncExecutionEvent <object, bool>())
            {
                for (int i = 0; i < 100; i++)
                {
                    bool unregistered = false;
                    bool badCall      = false;
                    AsyncExecutionEventCallback <object, bool> callbackAsync = (sender, arg) =>
                    {
                        // badCall should never be set to true here
                        // because unregistered is only set to true
                        // after Unregister has been called.
                        badCall = arg;
                        return(Task.CompletedTask);
                    };

                    executionEvent.Register(callbackAsync);

                    Task unregisterTask = Task.Run(async() =>
                    {
                        // In about half of the cases, we yield execution here.
                        // So that we randomize the order of the two tasks.
                        if (rnd.Next(100) >= 50)
                        {
                            await Task.Yield();
                        }
                        executionEvent.Unregister(callbackAsync);
                        unregistered = true;
                    });

                    Task callTask = Task.Run(async() =>
                    {
                        // Random delay to help randomize the order of two tasks.
                        await Task.Delay(rnd.Next(10));
                        await executionEvent.ExecuteCallbacksAsync(null, unregistered);
                    });

                    Task.WaitAll(unregisterTask, callTask);
                    Assert.False(badCall);
                }
            }
        }