1 namespace System.Web.Mvc { 2 using System; 3 using System.Web.Mvc.Async; 4 using System.Web.Routing; 5 6 public abstract class AsyncController : Controller, IAsyncManagerContainer, IAsyncController { 7 8 private static readonly object _executeTag = new object(); 9 private static readonly object _executeCoreTag = new object(); 10 11 private readonly AsyncManager _asyncManager = new AsyncManager(); 12 13 public AsyncManager AsyncManager { 14 get { 15 return _asyncManager; 16 } 17 } 18 BeginExecute(RequestContext requestContext, AsyncCallback callback, object state)19 protected virtual IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) { 20 if (requestContext == null) { 21 throw new ArgumentNullException("requestContext"); 22 } 23 24 VerifyExecuteCalledOnce(); 25 Initialize(requestContext); 26 return AsyncResultWrapper.Begin(callback, state, BeginExecuteCore, EndExecuteCore, _executeTag); 27 } 28 BeginExecuteCore(AsyncCallback callback, object state)29 protected virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) { 30 // If code in this method needs to be updated, please also check the ExecuteCore() method 31 // of Controller to see if that code also must be updated. 32 33 PossiblyLoadTempData(); 34 try { 35 string actionName = RouteData.GetRequiredString("action"); 36 IActionInvoker invoker = ActionInvoker; 37 IAsyncActionInvoker asyncInvoker = invoker as IAsyncActionInvoker; 38 if (asyncInvoker != null) { 39 // asynchronous invocation 40 BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) { 41 return asyncInvoker.BeginInvokeAction(ControllerContext, actionName, asyncCallback, asyncState); 42 }; 43 44 EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) { 45 if (!asyncInvoker.EndInvokeAction(asyncResult)) { 46 HandleUnknownAction(actionName); 47 } 48 }; 49 50 return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeCoreTag); 51 } 52 else { 53 // synchronous invocation 54 Action action = () => { 55 if (!invoker.InvokeAction(ControllerContext, actionName)) { 56 HandleUnknownAction(actionName); 57 } 58 }; 59 return AsyncResultWrapper.BeginSynchronous(callback, state, action, _executeCoreTag); 60 } 61 } 62 catch { 63 PossiblySaveTempData(); 64 throw; 65 } 66 } 67 CreateActionInvoker()68 protected override IActionInvoker CreateActionInvoker() { 69 return new AsyncControllerActionInvoker(); 70 } 71 EndExecute(IAsyncResult asyncResult)72 protected virtual void EndExecute(IAsyncResult asyncResult) { 73 AsyncResultWrapper.End(asyncResult, _executeTag); 74 } 75 EndExecuteCore(IAsyncResult asyncResult)76 protected virtual void EndExecuteCore(IAsyncResult asyncResult) { 77 // If code in this method needs to be updated, please also check the ExecuteCore() method 78 // of Controller to see if that code also must be updated. 79 80 try { 81 AsyncResultWrapper.End(asyncResult, _executeCoreTag); 82 } 83 finally { 84 PossiblySaveTempData(); 85 } 86 } 87 88 #region IAsyncController Members IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, object state)89 IAsyncResult IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) { 90 return BeginExecute(requestContext, callback, state); 91 } 92 IAsyncController.EndExecute(IAsyncResult asyncResult)93 void IAsyncController.EndExecute(IAsyncResult asyncResult) { 94 EndExecute(asyncResult); 95 } 96 #endregion 97 98 } 99 } 100