public void should_run_async_without_blocking_dispatcher_thread()
        {
            var tcs = new TaskCompletionSource <object>();

            var firstMessage = new AsyncExecutableEvent
            {
                Callback = async _ => await tcs.Task.ConfigureAwait(true)
            };

            var secondMessage = new AsyncExecutableEvent
            {
                Callback = _ =>
                {
                    tcs.SetResult(null);
                    return(TaskUtil.Completed);
                }
            };

            _dispatchQueue.Start();
            var firstTask  = EnqueueAsyncInvocation(firstMessage);
            var secondTask = EnqueueAsyncInvocation(secondMessage);

            Task.WhenAll(firstTask, secondTask).Wait(2000.Milliseconds()).ShouldBeTrue();

            firstMessage.DispatchQueueName.ShouldEqual(_dispatchQueue.Name);
            secondMessage.DispatchQueueName.ShouldEqual(_dispatchQueue.Name);
        }
        public void should_not_accept_invocations_after_stop_while_completing_async_invocations(bool captureContext)
        {
            var tcs = new TaskCompletionSource <object>();

            var message = new AsyncExecutableEvent {
                Callback = async _ => await tcs.Task.ConfigureAwait(captureContext)
            };

            _dispatchQueue.Start();
            EnqueueAsyncInvocation(message);

            message.HandleStarted.Wait(500.Milliseconds()).ShouldBeTrue();

            var stopTask = Task.Run(() => _dispatchQueue.Stop());

            Thread.Sleep(100);
            stopTask.IsCompleted.ShouldBeFalse();

            var afterStopMessage = new ExecutableEvent();

            EnqueueInvocation(afterStopMessage);
            Thread.Sleep(100);

            Task.Run(() => tcs.SetResult(null));
            stopTask.Wait(500.Milliseconds()).ShouldBeTrue();

            afterStopMessage.HandleStarted.IsSet.ShouldBeFalse();
        }
        private Task <DispatchResult> EnqueueAsyncInvocation(AsyncExecutableEvent message)
        {
            var tcs = new TaskCompletionSource <DispatchResult>();

            var dispatch = new MessageDispatch(MessageContext.CreateTest(), message, (d, r) => tcs.SetResult(r));

            dispatch.SetHandlerCount(1);

            var invoker = new TestAsyncMessageHandlerInvoker <AsyncExecutableEvent>();

            _dispatchQueue.Enqueue(dispatch, invoker);

            return(tcs.Task);
        }
        public void should_finish_async_invocations_before_stopping(bool captureContext)
        {
            var tcs = new TaskCompletionSource <object>();

            var message = new AsyncExecutableEvent {
                Callback = async _ => await tcs.Task.ConfigureAwait(captureContext)
            };

            _dispatchQueue.Start();
            var invocation = EnqueueAsyncInvocation(message);

            message.HandleStarted.Wait(500.Milliseconds()).ShouldBeTrue();

            var stopTask = Task.Run(() => _dispatchQueue.Stop());

            Thread.Sleep(100);
            stopTask.IsCompleted.ShouldBeFalse();

            Task.Run(() => tcs.SetResult(null));
            invocation.Wait(500.Milliseconds()).ShouldBeTrue();
            stopTask.Wait(500.Milliseconds()).ShouldBeTrue();
        }