Exemplo n.º 1
0
        public void Send_CapturesContext()
        {
            // Arrange
            var context = new CircuitSynchronizationContext();

            var e1 = new ManualResetEventSlim();

            // CultureInfo uses the execution context.
            CultureInfo.CurrentCulture = new CultureInfo("en-GB");
            CultureInfo capturedCulture = null;

            SynchronizationContext capturedContext = null;

            // Act
            context.Send(async(_) =>
            {
                await Task.Yield();

                capturedCulture = CultureInfo.CurrentCulture;
                capturedContext = SynchronizationContext.Current;

                e1.Set();
            }, null);

            // Assert
            Assert.True(e1.Wait(Timeout), "timeout");
            Assert.Same(CultureInfo.CurrentCulture, capturedCulture);
            Assert.Same(context, capturedContext);
        }
Exemplo n.º 2
0
        public async Task Post_BackgroundWorkItem_CanProcessMoreItemsInline()
        {
            // Arrange
            var    context        = new CircuitSynchronizationContext();
            Thread capturedThread = null;

            var e1 = new ManualResetEventSlim();
            var e2 = new ManualResetEventSlim();
            var e3 = new ManualResetEventSlim();
            var e4 = new ManualResetEventSlim();
            var e5 = new ManualResetEventSlim();
            var e6 = new ManualResetEventSlim();

            // Force task2 to execute in the background
            var task1 = Task.Run(() => context.Send((_) =>
            {
                e1.Set();
                Assert.True(e2.Wait(Timeout), "timeout");
            }, null));

            Assert.True(e1.Wait(Timeout), "timeout");

            var task2 = Task.Run(() =>
            {
                context.Send((_) =>
                {
                    e3.Set();
                    Assert.True(e4.Wait(Timeout), "timeout");
                    capturedThread = Thread.CurrentThread;
                }, null);
            });

            e2.Set();
            await task1;

            Assert.True(e3.Wait(Timeout), "timeout");

            // Act
            //
            // Now task2 is 'running' in the sync context. Schedule more work items - they will be
            // run immediately after the second item
            context.Post((_) =>
            {
                e5.Set();
                Assert.Same(Thread.CurrentThread, capturedThread);
            }, null);
            context.Post((_) =>
            {
                e6.Set();
                Assert.Same(Thread.CurrentThread, capturedThread);
            }, null);


            // Assert
            e4.Set();
            await task2;

            Assert.True(e5.Wait(Timeout), "timeout");
            Assert.True(e6.Wait(Timeout), "timeout");
        }
Exemplo n.º 3
0
        public void Post_CanRunSynchronously_WhenNotBusy_Exception()
        {
            // Arrange
            var context = new CircuitSynchronizationContext();

            // Act & Assert
            Assert.Throws <InvalidTimeZoneException>(() => context.Post((_) =>
            {
                throw new InvalidTimeZoneException();
            }, null));
        }
Exemplo n.º 4
0
        public async Task Post_CanRunAsynchronously_CaptureExecutionContext()
        {
            // Arrange
            var context = new CircuitSynchronizationContext();

            // CultureInfo uses the execution context.
            CultureInfo.CurrentCulture = new CultureInfo("en-GB");
            CultureInfo capturedCulture = null;

            SynchronizationContext capturedContext = null;

            var e1 = new ManualResetEventSlim();
            var e2 = new ManualResetEventSlim();
            var e3 = new ManualResetEventSlim();

            var task = Task.Run(() =>
            {
                context.Send((_) =>
                {
                    e1.Set();
                    Assert.True(e2.Wait(Timeout), "timeout");
                }, null);
            });

            Assert.True(e1.Wait(Timeout), "timeout");

            // Act
            SynchronizationContext original = SynchronizationContext.Current;

            try
            {
                SynchronizationContext.SetSynchronizationContext(context);
                context.Post((_) =>
                {
                    capturedCulture = CultureInfo.CurrentCulture;
                    capturedContext = SynchronizationContext.Current;
                    e3.Set();
                }, null);
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(original);
            }

            // Assert
            Assert.False(e2.IsSet);
            e2.Set(); // Unblock the first item
            await task;

            Assert.True(e3.Wait(Timeout), "timeout");
            Assert.Same(CultureInfo.CurrentCulture, capturedCulture);
            Assert.Same(context, capturedContext);
        }
Exemplo n.º 5
0
        public async Task InvokeAsync_T_CanRethrowExceptions()
        {
            // Arrange
            var context = new CircuitSynchronizationContext();

            // Act
            var task = context.InvokeAsync <string>(() =>
            {
                throw new InvalidTimeZoneException();
            });

            // Assert
            await Assert.ThrowsAsync <InvalidTimeZoneException>(async() => await task);
        }
Exemplo n.º 6
0
        public async Task InvokeAsync_T_CanRunSynchronously_WhenNotBusy()
        {
            // Arrange
            var context = new CircuitSynchronizationContext();
            var thread  = Thread.CurrentThread;

            // Act
            var task = context.InvokeAsync(() =>
            {
                return(Task.FromResult(Thread.CurrentThread));
            });

            // Assert
            Assert.Same(thread, await task);
        }
Exemplo n.º 7
0
        public void Send_CanRunSynchonously()
        {
            // Arrange
            var    context        = new CircuitSynchronizationContext();
            var    thread         = Thread.CurrentThread;
            Thread capturedThread = null;

            // Act
            context.Send((_) =>
            {
                capturedThread = Thread.CurrentThread;
            }, null);

            // Assert
            Assert.Same(thread, capturedThread);
        }
Exemplo n.º 8
0
        public async Task Send_BlocksWhenOtherWorkRunning()
        {
            // Arrange
            var context = new CircuitSynchronizationContext();

            var e1 = new ManualResetEventSlim();
            var e2 = new ManualResetEventSlim();
            var e3 = new ManualResetEventSlim();
            var e4 = new ManualResetEventSlim();

            // Force task2 to execute in the background
            var task1 = Task.Run(() =>
            {
                context.Send((_) =>
                {
                    e1.Set();
                    Assert.True(e2.Wait(Timeout), "timeout");
                }, null);
            });

            Assert.True(e1.Wait(Timeout), "timeout");

            // Act
            //
            // Dispatch this on the background thread because otherwise it would block.
            var task2 = Task.Run(() =>
            {
                e3.Set();
                context.Send((_) =>
                {
                    e4.Set();
                }, null);
            });

            // Assert
            Assert.True(e3.Wait(Timeout), "timeout");
            Assert.True(e3.IsSet);

            // Unblock the first item
            e2.Set();
            await task1;

            await task2;

            Assert.True(e4.IsSet);
        }
Exemplo n.º 9
0
        public async Task Invoke_Void_CanRunSynchronously_WhenNotBusy()
        {
            // Arrange
            var    context        = new CircuitSynchronizationContext();
            var    thread         = Thread.CurrentThread;
            Thread capturedThread = null;

            // Act
            var task = context.Invoke(() =>
            {
                capturedThread = Thread.CurrentThread;
            });

            // Assert
            await task;

            Assert.Same(thread, capturedThread);
        }
Exemplo n.º 10
0
        public async Task Post_CanRunAsynchronously_WhenBusy_Exception()
        {
            // Arrange
            var context = new CircuitSynchronizationContext();

            Exception exception = null;

            context.UnhandledException += (sender, e) =>
            {
                exception = (InvalidTimeZoneException)e.ExceptionObject;
            };

            var e1 = new ManualResetEventSlim();
            var e2 = new ManualResetEventSlim();

            var task = Task.Run(() =>
            {
                context.Send((_) =>
                {
                    e1.Set();
                    Assert.True(e2.Wait(Timeout), "timeout");
                }, null);
            });

            Assert.True(e1.Wait(Timeout), "timeout");

            // Act
            context.Post((_) =>
            {
                throw new InvalidTimeZoneException();
            }, null);

            // Assert
            Assert.False(e2.IsSet);
            e2.Set(); // Unblock the first item
            await task;

            // Use another item to 'push through' the throwing one
            context.Send((_) => { }, null);
            Assert.NotNull(exception);
        }
Exemplo n.º 11
0
        public async Task InvokeAsync_Void_CanRunAsynchronously_WhenBusy()
        {
            // Arrange
            var    context        = new CircuitSynchronizationContext();
            var    thread         = Thread.CurrentThread;
            Thread capturedThread = null;

            var e1 = new ManualResetEventSlim();
            var e2 = new ManualResetEventSlim();
            var e3 = new ManualResetEventSlim();

            var task1 = Task.Run(() =>
            {
                context.Send((_) =>
                {
                    e1.Set();
                    Assert.True(e2.Wait(Timeout), "timeout");
                }, null);
            });

            Assert.True(e1.Wait(Timeout), "timeout");

            var task2 = context.InvokeAsync(() =>
            {
                capturedThread = Thread.CurrentThread;

                e3.Set();
                return(Task.CompletedTask);
            });

            // Assert
            Assert.False(e2.IsSet);
            e2.Set(); // Unblock the first item
            await task1;

            Assert.True(e3.Wait(Timeout), "timeout");
            await task2;

            Assert.NotSame(thread, capturedThread);
        }