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)); }
public void WrapThrowsIfEndCallbackIsNull() { // Arrange BeginInvokeCallback beginCallback = (callback, state) => null; // Act & assert ExceptionHelper.ExpectArgumentNullException( delegate { AsyncResultWrapper.Wrap(null, null, beginCallback, null); }, "endCallback"); }
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"); }
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)); }
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 */)); }
public static IAsyncResult Wrap(AsyncCallback callback, object state, BeginInvokeCallback beginCallback, AsyncCallback endCallback, object tag) { return(WrapWithTimeout(callback, state, beginCallback, endCallback, Timeout.Infinite, tag)); }
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); }
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)); } }