Пример #1
0
        protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
        {
            AddVersionHeader(httpContext);

            // Get the controller type
            string controllerName = RequestContext.RouteData.GetRequiredString("controller");

            // Instantiate the controller and call Execute
            IControllerFactory factory    = ControllerBuilder.GetControllerFactory();
            IController        controller = factory.CreateController(RequestContext, controllerName);

            if (controller == null)
            {
                throw new InvalidOperationException(
                          String.Format(
                              CultureInfo.CurrentUICulture,
                              MvcResources.ControllerBuilder_FactoryReturnedNull,
                              factory.GetType(),
                              controllerName));
            }

            BeginExecuteDelegate beginExecute;
            EndExecuteDelegate   endExecute;

            IAsyncController asyncController = controller as IAsyncController;

            if (asyncController != null)
            {
                beginExecute = asyncController.BeginExecute;
                endExecute   = asyncController.EndExecute;
            }
            else
            {
                // execute synchronous controller asynchronously
                ExecuteDelegate executeDelegate = rc => SynchronizationContext.Sync(() => controller.Execute(rc));
                beginExecute = executeDelegate.BeginInvoke;
                endExecute   = executeDelegate.EndInvoke;
            }

            BeginInvokeCallback beginCallback = (innerCallback, innerState) => {
                try {
                    return(beginExecute(RequestContext, innerCallback, innerState));
                }
                catch {
                    factory.ReleaseController(controller);
                    throw;
                }
            };

            AsyncCallback endCallback = ar => {
                try {
                    endExecute(ar);
                }
                finally {
                    factory.ReleaseController(controller);
                }
            };

            return(AsyncResultWrapper.Wrap(callback, state, beginCallback, endCallback, _processRequestTag));
        }
Пример #2
0
        public void WrapThrowsIfEndCallbackIsNull()
        {
            // Arrange
            BeginInvokeCallback beginCallback = (callback, state) => null;

            // Act & assert
            ExceptionHelper.ExpectArgumentNullException(
                delegate {
                AsyncResultWrapper.Wrap(null, null, beginCallback, null);
            }, "endCallback");
        }
Пример #3
0
        public void WrapThrowsIfTimeoutIsOutOfRange()
        {
            // Arrange
            BeginInvokeCallback beginCallback = (callback, state) => null;
            AsyncCallback       endCallback   = ar => { };

            // Act & assert
            ExceptionHelper.ExpectArgumentOutOfRangeException(
                delegate {
                AsyncResultWrapper.WrapWithTimeout(null, null, beginCallback, endCallback, -1000);
            }, "timeout",
                @"The timeout period must be a non-negative number or Timeout.Infinite.
Parameter name: timeout");
        }
Пример #4
0
        private static IAsyncResult CreateInvokeActionNotFoundAsyncResult(AsyncCallback callback, object state)
        {
            BeginInvokeCallback beginCallback = (innerCallback, innerState) => {
                ManualAsyncResult asyncResult = new ManualAsyncResult()
                {
                    AsyncState = innerState
                };
                asyncResult.MarkCompleted(true /* completedSynchronously */, innerCallback);
                return(asyncResult);
            };
            AsyncCallback <bool> endCallback = ar => {
                return(false);
            };

            return(AsyncResultWrapper.Wrap(callback, state, beginCallback, endCallback, _invokeActionTag));
        }
Пример #5
0
        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");
            }

            ParameterInfo[]      parameterInfos     = BeginMethod.GetParameters();
            IEnumerable <object> rawParameterValues = from parameterInfo in parameterInfos
                                                      select ExtractParameterFromDictionary(parameterInfo, parameters, BeginMethod);

            List <object> parametersList = rawParameterValues.Take(parameterInfos.Length - 2).ToList();

            MethodDispatcher beginDispatcher = DispatcherCache.GetDispatcher(BeginMethod);
            MethodDispatcher endDispatcher   = DispatcherCache.GetDispatcher(EndMethod);

            // need to add callback + state object to list
            BeginInvokeCallback beginCallback = (innerCallback, innerState) => {
                parametersList.Add(innerCallback);
                parametersList.Add(innerState);
                object[] parametersArray = parametersList.ToArray();

                IAsyncResult innerAsyncResult = (IAsyncResult)beginDispatcher.Execute(controllerContext.Controller, parametersArray);
                return(innerAsyncResult);
            };

            AsyncCallback <object> endCallback = ar => {
                object actionReturnValue = endDispatcher.Execute(controllerContext.Controller, new object[] { ar });
                return(actionReturnValue);
            };

            // Set the timeout and go
            IAsyncManagerContainer helperContainer = controllerContext.Controller as IAsyncManagerContainer;
            int timeout = (helperContainer != null) ? helperContainer.AsyncManager.Timeout : Timeout.Infinite;

            return(AsyncResultWrapper.WrapWithTimeout(callback, state, beginCallback, endCallback, timeout, _executeTag));
        }
        internal static IAsyncResult BeginInvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, BeginInvokeCallback beginContinuation, AsyncCallback<ActionExecutedContext> endContinuation, AsyncCallback callback, object state) {
            filter.OnActionExecuting(preContext);
            if (preContext.Result != null) {
                ActionExecutedContext shortCircuitContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) {
                    Result = preContext.Result
                };
                return new ObjectAsyncResult<ActionExecutedContext>(shortCircuitContext).ToAsyncResultWrapper(callback, state);
            }

            try {
                return AsyncResultWrapper.Wrap(callback, state, beginContinuation,
                    ar => BeginInvokeActionMethodFilterEndContinuation(filter, preContext, () => endContinuation(ar)));
            }
            catch (ThreadAbortException) {
                // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
                // the filters don't see this as an error.
                ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */);
                filter.OnActionExecuted(postContext);
                throw;
            }
            catch (Exception ex) {
                ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex);
                filter.OnActionExecuted(postContext);
                if (!postContext.ExceptionHandled) {
                    throw;
                }

                return new ObjectAsyncResult<ActionExecutedContext>(postContext).ToAsyncResultWrapper(callback, state);
            }
        }
        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));
        }
 public static IAsyncResult WrapWithTimeout <TResult>(AsyncCallback callback, object state, BeginInvokeCallback beginCallback, AsyncCallback <TResult> endCallback, int timeout, object tag)
 {
     ValidateParameters(beginCallback, endCallback, timeout);
     return(WrapWithTimeoutInternal(callback, state, beginCallback, endCallback, timeout, tag));
 }
 public static IAsyncResult WrapWithTimeout <TResult>(AsyncCallback callback, object state, BeginInvokeCallback beginCallback, AsyncCallback <TResult> endCallback, int timeout)
 {
     return(WrapWithTimeout(callback, state, beginCallback, endCallback, timeout, null /* tag */));
 }
Пример #10
0
 public static IAsyncResult Wrap(AsyncCallback callback, object state, BeginInvokeCallback beginCallback, AsyncCallback endCallback, object tag)
 {
     return(WrapWithTimeout(callback, state, beginCallback, endCallback, Timeout.Infinite, tag));
 }
Пример #11
0
        private static IAsyncResult WrapWithTimeoutInternal <TResult>(AsyncCallback callback, object state, BeginInvokeCallback beginCallback, AsyncCallback <TResult> endCallback, int timeout, object tag)
        {
            AsyncResultWrapperImpl <TResult> wrapper = new AsyncResultWrapperImpl <TResult>()
            {
                Callback      = callback,
                AsyncState    = state,
                BeginCallback = beginCallback,
                EndCallback   = endCallback,
                Tag           = tag,
                Timeout       = timeout
            };

            wrapper.ExecuteBeginDelegate();
            return(wrapper);
        }
Пример #12
0
        internal static IAsyncResult BeginInvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, BeginInvokeCallback beginContinuation, AsyncCallback <ActionExecutedContext> endContinuation, AsyncCallback callback, object state)
        {
            filter.OnActionExecuting(preContext);
            if (preContext.Result != null)
            {
                ActionExecutedContext shortCircuitContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */)
                {
                    Result = preContext.Result
                };
                return(new ObjectAsyncResult <ActionExecutedContext>(shortCircuitContext).ToAsyncResultWrapper(callback, state));
            }

            try {
                return(AsyncResultWrapper.Wrap(callback, state, beginContinuation,
                                               ar => BeginInvokeActionMethodFilterEndContinuation(filter, preContext, () => endContinuation(ar))));
            }
            catch (ThreadAbortException) {
                // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
                // the filters don't see this as an error.
                ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */);
                filter.OnActionExecuted(postContext);
                throw;
            }
            catch (Exception ex) {
                ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex);
                filter.OnActionExecuted(postContext);
                if (!postContext.ExceptionHandled)
                {
                    throw;
                }

                return(new ObjectAsyncResult <ActionExecutedContext>(postContext).ToAsyncResultWrapper(callback, state));
            }
        }