Example #1
0
        public async Task AsyncMethodMutatesGlobalStateWithAwait()
        {
            const int expected = 7;

            await AsyncMethods.MutateGlobalStateAfterASecondAsync(expected);

            Assert.AreEqual(expected, MutableGlobalState.State);
        }
Example #2
0
        public async Task AsyncMethodReturnsTaskOfT()
        {
            const string expected = "foo";

            var actual = await AsyncMethods
                         .WaitASecondAndReturnAValueAsync(expected);

            Assert.AreEqual(expected, actual);
        }
Example #3
0
        public void SomeProblemWithGetAwaiterGetResult()
        {
            var blockingSyncContext = new WindowsFormsSynchronizationContext();

            SynchronizationContext.SetSynchronizationContext(blockingSyncContext);
            var theValue = AsyncMethods
                           .WaitASecondAndReturnAValueAsync("this too is doomed")
                           .GetAwaiter()
                           .GetResult();
        }
Example #4
0
        public void HowDoIFixThisDeadLockByUsingConfigureAwaitFalse()
        {
            var blockingSyncContext = new WindowsFormsSynchronizationContext();

            SynchronizationContext.SetSynchronizationContext(blockingSyncContext);

            var theValue = AsyncMethods
                           .WaitASecondAndReturnAValueAsyncAwaitFalse("this works around it")
                           .GetAwaiter()
                           .GetResult();

            Assert.AreEqual("this works around it", theValue);
        }
Example #5
0
        public void ItCreatesADeadLockWhenCertainSyncContextsGetInvolved()
        {
            var blockingSyncContext = new WindowsFormsSynchronizationContext();

            SynchronizationContext.SetSynchronizationContext(blockingSyncContext);

            // Result is invoked on the same thread as the blocking sync context
            // Because the sync context blocked when calling the async method,
            // The call to result is deadlocked as it's waiting for the original call
            // to release the thread.
            // A way to see this visually is to execute this from a GUI, it would become non responsive.
            var theValue = AsyncMethods
                           .WaitASecondAndReturnAValueAsync("this is doomed to deadlock")
                           .Result;
        }
Example #6
0
        public void HowDoIFixThisDeadLockByAllowingCompletionOnADifferentThread()
        {
            var blockingSyncContext = new WindowsFormsSynchronizationContext();

            SynchronizationContext.SetSynchronizationContext(blockingSyncContext);
            Func <Task <string> > returnValueFunc = () => AsyncMethods
                                                    .WaitASecondAndReturnAValueAsync("this works around it");

            //this now executes on a different thread
            //and wont deadlock when calling result
            var theValue = Task
                           .Run(returnValueFunc)
                           .Result;

            Assert.AreEqual("this works around it", theValue);
        }
Example #7
0
        public void IGetBetterExceptionInformationWhenUsingGetAwaiterGetResult()
        {
            Assert.Throws <AggregateException>(() =>
            {
                var resultThatWillNeverBe = AsyncMethods
                                            .ThrowAnExceptionAfterNSecondAsync(1)
                                            .Result;
            }, "Using result gives you an aggregate exception and this is not as nice as...");

            Assert.Throws <SuperSpecificException>(() =>
            {
                var resultThatWillNeverBe = AsyncMethods
                                            .ThrowAnExceptionAfterNSecondAsync(1)
                                            .GetAwaiter()
                                            .GetResult();
            }, "Using get awaiter, and then get result, actually throws the original exception from the awaiter");
        }
Example #8
0
        public async Task WhatHappensWhenTwoOperationsThrowAnExceptionWhenAll()
        {
            Exception exceptionThrowByA = null;
            Exception exceptionThrowByB = null;

            var aWithExceptionHandler = AsyncMethods
                                        .ThrowAnExceptionAfterNSecondAsync(1)
                                        .ContinueWith(task => exceptionThrowByA = task.Exception);


            var bWithExceptionHandler = AsyncMethods
                                        .ThrowAnExceptionAfterNSecondAsync(2)
                                        .ContinueWith(task => exceptionThrowByB = task.Exception);

            await Task.WhenAll
                (aWithExceptionHandler,
                bWithExceptionHandler);

            Assert.IsNotNull(exceptionThrowByA, "a - exception is missing");
            Assert.IsNotNull(exceptionThrowByB, "b - exception is missing");
        }