public void ParametersProperty() {
            // Act
            AsyncManager helper = new AsyncManager();

            // Assert
            Assert.IsNotNull(helper.Parameters);
        }
        public void OutstandingOperationsProperty() {
            // Act
            AsyncManager helper = new AsyncManager();

            // Assert
            Assert.IsNotNull(helper.OutstandingOperations);
        }
        public void Post() {
            // Arrange
            Mock<SynchronizationContext> mockSyncContext = new Mock<SynchronizationContext>();
            mockSyncContext
                .Expect(c => c.Send(It.IsAny<SendOrPostCallback>(), null))
                .Callback(
                    delegate(SendOrPostCallback d, object state) {
                        d(state);
                    });

            AsyncManager helper = new AsyncManager(mockSyncContext.Object);
            bool wasCalled = false;

            // Act
            helper.Post(() => { wasCalled = true; });

            // Assert
            Assert.IsTrue(wasCalled);
        }
Example #4
0
        public static void RegisterTask(this AsyncManager asyncManager, Func <AsyncCallback, IAsyncResult> beginDelegate, Action <IAsyncResult> endDelegate)
        {
            if (asyncManager == null)
            {
                throw new ArgumentNullException("asyncManager");
            }
            if (beginDelegate == null)
            {
                throw new ArgumentNullException("beginDelegate");
            }
            if (endDelegate == null)
            {
                throw new ArgumentNullException("endDelegate");
            }

            // need to wait to execute the callback until after BeginXxx() has completed
            object delegateExecutingLockObj = new object();

            AsyncCallback callback = ar =>
            {
                lock (delegateExecutingLockObj)
                {
                    // this empty lock is required to synchronized with the beginDelegate call
                }
                if (!ar.CompletedSynchronously)
                {
                    try
                    {
                        asyncManager.Sync(() => endDelegate(ar)); // called on different thread, so have to take application lock
                    }
                    catch
                    {
                        // Need to swallow exceptions, as otherwise unhandled exceptions on a ThreadPool thread
                        // can bring down the entire worker process.
                    }
                    finally
                    {
                        asyncManager.OutstandingOperations.Decrement();
                    }
                }
            };

            IAsyncResult asyncResult;

            asyncManager.OutstandingOperations.Increment();
            try
            {
                lock (delegateExecutingLockObj)
                {
                    asyncResult = beginDelegate(callback);
                }
            }
            catch
            {
                asyncManager.OutstandingOperations.Decrement();
                throw;
            }

            if (asyncResult.CompletedSynchronously)
            {
                try
                {
                    endDelegate(asyncResult); // call on same thread
                }
                finally
                {
                    asyncManager.OutstandingOperations.Decrement();
                }
            }
        }
        public void TimeoutPropertyThrowsIfDurationIsOutOfRangs() {
            // Arrange
            int timeout = -30;
            AsyncManager helper = new AsyncManager();

            // Act & assert
            ExceptionHelper.ExpectArgumentOutOfRangeException(
                delegate {
                    helper.Timeout = timeout;
                }, "value",
                @"The timeout period must be a non-negative number or Timeout.Infinite.
Parameter name: value");
        }
        public void TimeoutProperty() {
            // Arrange
            int setValue = 50;
            AsyncManager helper = new AsyncManager();

            // Act
            int defaultTimeout = helper.Timeout;
            helper.Timeout = setValue;
            int newTimeout = helper.Timeout;

            // Assert
            Assert.AreEqual(30000, defaultTimeout);
            Assert.AreEqual(setValue, newTimeout);
        }
        public void SynchronizationContextProperty() {
            // Arrange
            SynchronizationContext syncContext = new SynchronizationContext();

            // Act
            AsyncManager helper = new AsyncManager(syncContext);

            // Assert
            Assert.AreEqual(syncContext, helper.SynchronizationContext);
        }
        public override IAsyncResult BeginExecute(ControllerContext controllerContext, IDictionary <string, object> parameters, AsyncCallback callback, object state)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            AsyncManager    asyncHelper         = GetAsyncManager(controllerContext.Controller);
            SingleFireEvent setupCompletedEvent = new SingleFireEvent();

            BeginInvokeCallback beginCallback = (innerCallback, innerState) => {
                ManualAsyncResult asyncResult = new ManualAsyncResult()
                {
                    AsyncState = innerState
                };

                // Get parameters for async setup method, then execute
                ParameterInfo[] setupParametersInfos    = SetupMethod.GetParameters();
                var             rawSetupParameterValues = from parameterInfo in setupParametersInfos
                                                          select ExtractParameterFromDictionary(parameterInfo, parameters, SetupMethod);

                object[] setupParametersArray = rawSetupParameterValues.ToArray();

                // to simplify the logic, force an asynchronous callback
                asyncHelper.OutstandingOperations.Completed += delegate {
                    if (setupCompletedEvent.Signal())
                    {
                        ThreadPool.QueueUserWorkItem(o => {
                            asyncResult.MarkCompleted(false /* completedSynchronously */, innerCallback);
                        });
                    }
                };

                MethodDispatcher setupDispatcher = DispatcherCache.GetDispatcher(SetupMethod);
                asyncHelper.OutstandingOperations.Increment();
                setupDispatcher.Execute(controllerContext.Controller, setupParametersArray);
                asyncHelper.OutstandingOperations.Decrement();
                return(asyncResult);
            };

            AsyncCallback <object> endCallback = ar => {
                if (setupCompletedEvent.Signal())
                {
                    // the setup method did not complete before this callback executed
                    throw new InvalidOperationException(MvcResources.AsyncActionDescriptor_EndExecuteCalledPrematurely);
                }

                // Get parameters for action method, then execute
                ParameterInfo[] completionParametersInfos    = CompletionMethod.GetParameters();
                var             rawCompletionParameterValues = from parameterInfo in completionParametersInfos
                                                               select ExtractParameterOrDefaultFromDictionary(parameterInfo, asyncHelper.Parameters);

                object[] completionParametersArray = rawCompletionParameterValues.ToArray();

                MethodDispatcher completionDispatcher = DispatcherCache.GetDispatcher(CompletionMethod);
                object           actionReturnValue    = completionDispatcher.Execute(controllerContext.Controller, completionParametersArray);
                return(actionReturnValue);
            };

            // Set the timeout and go
            int timeout = asyncHelper.Timeout;

            return(AsyncResultWrapper.WrapWithTimeout(callback, state, beginCallback, endCallback, timeout, _executeTag));
        }