1 /* ****************************************************************************
\r
3 * Copyright (c) Microsoft Corporation. All rights reserved.
\r
5 * This software is subject to the Microsoft Public License (Ms-PL).
\r
6 * A copy of the license can be found in the license.htm file included
\r
7 * in this distribution.
\r
9 * You must not remove this notice, or any other, from this software.
\r
11 * ***************************************************************************/
\r
13 namespace System.Web.Mvc {
\r
15 using System.Web.Mvc.Async;
\r
16 using System.Web.Routing;
\r
18 public abstract class AsyncController : Controller, IAsyncManagerContainer, IAsyncController {
\r
20 private static readonly object _executeTag = new object();
\r
21 private static readonly object _executeCoreTag = new object();
\r
23 private readonly AsyncManager _asyncManager = new AsyncManager();
\r
25 public AsyncManager AsyncManager {
\r
27 return _asyncManager;
\r
31 protected virtual IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) {
\r
32 if (requestContext == null) {
\r
33 throw new ArgumentNullException("requestContext");
\r
36 VerifyExecuteCalledOnce();
\r
37 Initialize(requestContext);
\r
38 return AsyncResultWrapper.Begin(callback, state, BeginExecuteCore, EndExecuteCore, _executeTag);
\r
41 protected virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) {
\r
42 // If code in this method needs to be updated, please also check the ExecuteCore() method
\r
43 // of Controller to see if that code also must be updated.
\r
45 PossiblyLoadTempData();
\r
47 string actionName = RouteData.GetRequiredString("action");
\r
48 IActionInvoker invoker = ActionInvoker;
\r
49 IAsyncActionInvoker asyncInvoker = invoker as IAsyncActionInvoker;
\r
50 if (asyncInvoker != null) {
\r
51 // asynchronous invocation
\r
52 BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
\r
53 return asyncInvoker.BeginInvokeAction(ControllerContext, actionName, asyncCallback, asyncState);
\r
56 EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) {
\r
57 if (!asyncInvoker.EndInvokeAction(asyncResult)) {
\r
58 HandleUnknownAction(actionName);
\r
62 return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeCoreTag);
\r
65 // synchronous invocation
\r
66 Action action = () => {
\r
67 if (!invoker.InvokeAction(ControllerContext, actionName)) {
\r
68 HandleUnknownAction(actionName);
\r
71 return AsyncResultWrapper.BeginSynchronous(callback, state, action, _executeCoreTag);
\r
75 PossiblySaveTempData();
\r
80 protected override IActionInvoker CreateActionInvoker() {
\r
81 return new AsyncControllerActionInvoker();
\r
84 protected virtual void EndExecute(IAsyncResult asyncResult) {
\r
85 AsyncResultWrapper.End(asyncResult, _executeTag);
\r
88 protected virtual void EndExecuteCore(IAsyncResult asyncResult) {
\r
89 // If code in this method needs to be updated, please also check the ExecuteCore() method
\r
90 // of Controller to see if that code also must be updated.
\r
93 AsyncResultWrapper.End(asyncResult, _executeCoreTag);
\r
96 PossiblySaveTempData();
\r
100 #region IAsyncController Members
\r
101 IAsyncResult IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) {
\r
102 return BeginExecute(requestContext, callback, state);
\r
105 void IAsyncController.EndExecute(IAsyncResult asyncResult) {
\r
106 EndExecute(asyncResult);
\r