public override ICollection <ActionSelector> GetSelectors()
        {
            // By default, we only look at filters on the XxxAsync() method.

            ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])AsyncMethodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */);
            ActionSelector[] selectors            = Array.ConvertAll(attrs, attr => (ActionSelector)(controllerContext => attr.IsValidForRequest(controllerContext, AsyncMethodInfo)));
            return(selectors);
        }
        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 asyncManager = GetAsyncManager(controllerContext.Controller);

            BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
                // call the XxxAsync() method
                ParameterInfo[] parameterInfos     = AsyncMethodInfo.GetParameters();
                var             rawParameterValues = from parameterInfo in parameterInfos
                                                     select ExtractParameterFromDictionary(parameterInfo, parameters, AsyncMethodInfo);

                object[] parametersArray = rawParameterValues.ToArray();

                TriggerListener   listener    = new TriggerListener();
                SimpleAsyncResult asyncResult = new SimpleAsyncResult(asyncState);

                // hook the Finished event to notify us upon completion
                Trigger finishTrigger = listener.CreateTrigger();
                asyncManager.Finished += delegate { finishTrigger.Fire(); };
                asyncManager.OutstandingOperations.Increment();

                // to simplify the logic, force the rest of the pipeline to execute in an asynchronous callback
                listener.SetContinuation(() => ThreadPool.QueueUserWorkItem(_ => asyncResult.MarkCompleted(false /* completedSynchronously */, asyncCallback)));

                // the inner operation might complete synchronously, so all setup work has to be done before this point
                ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(AsyncMethodInfo);
                dispatcher.Execute(controllerContext.Controller, parametersArray); // ignore return value from this method

                // now that the XxxAsync() method has completed, kick off any pending operations
                asyncManager.OutstandingOperations.Decrement();
                listener.Activate();
                return(asyncResult);
            };

            EndInvokeDelegate <object> endDelegate = delegate(IAsyncResult asyncResult) {
                // call the XxxCompleted() method
                ParameterInfo[] completionParametersInfos    = CompletedMethodInfo.GetParameters();
                var             rawCompletionParameterValues = from parameterInfo in completionParametersInfos
                                                               select ExtractParameterOrDefaultFromDictionary(parameterInfo, asyncManager.Parameters);

                object[] completionParametersArray = rawCompletionParameterValues.ToArray();

                ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(CompletedMethodInfo);
                object actionReturnValue          = dispatcher.Execute(controllerContext.Controller, completionParametersArray);
                return(actionReturnValue);
            };

            return(AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeTag, asyncManager.Timeout));
        }
 public override bool IsDefined(Type attributeType, bool inherit)
 {
     return(AsyncMethodInfo.IsDefined(attributeType, inherit));
 }
 public override object[] GetCustomAttributes(Type attributeType, bool inherit)
 {
     return(AsyncMethodInfo.GetCustomAttributes(attributeType, inherit));
 }
 public override object[] GetCustomAttributes(bool inherit)
 {
     return(AsyncMethodInfo.GetCustomAttributes(inherit));
 }