Use ASP. net mvc source code to find a solution

Source: Internet
Author: User

ASP. net mvc source code to find a solution. Because the BeginXxx method can be called in the Action method, we only need to retain the IAsyncResult returned by the Begin method in AsyncActionResult, and another reference to the EndXxx method. The two objects will be saved in the ExecuteResult method of AsyncActionResult to be retrieved and used again in the EndProcessRequest method of AsyncMvcHandler. According to the "Convention", we also need to define an extension method so that developers can return an AsyncActionResult in the Action method. The specific implementation is very easy. Here we will show how to write asynchronous actions:

 
 
  1. [AsyncAction]  
  2. publicActionResultAsyncAction(AsyncCallbackasyncCallback,objectasyncState)  
  3. {  
  4. SqlConnectionconn=newSqlConnection("...;AsynchronousProcessing=true");  
  5. SqlCommandcmd=newSqlCommand("WAITFORDELAY'00:00:03';",conn);  
  6. conn.Open();  
  7.  
  8. returnthis.Async(  
  9. cmd.BeginExecuteNonQuery(asyncCallback,asyncState),  
  10. (ar)=> 
  11. {  
  12. intvalue=cmd.EndExecuteNonQuery(ar);  
  13. conn.Close();  
  14. returnthis.View();  
  15. });  

At this point, it seems that AsyncMvcHandler has no secret at all:

 
 
  1. publicclassAsyncMvcHandler:IHttpAsyncHandler,IRequiresSessionState  
  2. {  
  3. publicAsyncMvcHandler(  
  4. Controllercontroller,  
  5. IControllerFactorycontrollerFactory,  
  6. RequestContextrequestContext)  
  7. {  
  8. this.Controller=controller;  
  9. this.ControllerFactory=controllerFactory;  
  10. this.RequestContext=requestContext;  
  11. }  
  12.  
  13. publicControllerController{get;privateset;}  
  14. publicRequestContextRequestContext{get;privateset;}  
  15. publicIControllerFactoryControllerFactory{get;privateset;}  
  16. publicHttpContextContext{get;privateset;}  
  17.  
  18. publicIAsyncResultBeginProcessRequest(  
  19. HttpContextcontext,  
  20. AsyncCallbackcb,  
  21. objectextraData)  
  22. {  
  23. this.Context=context;  
  24. this.Controller.SetAsyncCallback(cb).SetAsyncState(extraData);  
  25.  
  26. try  
  27. {  
  28. (this.ControllerasIController).Execute(this.RequestContext);  
  29. returnthis.Controller.GetAsyncResult();  
  30. }  
  31. catch  
  32. {  
  33. this.ControllerFactory.ReleaseController(this.Controller);  
  34. throw;  
  35. }  
  36. }  
  37.  
  38. publicvoidEndProcessRequest(IAsyncResultresult)  
  39. {  
  40. try  
  41. {  
  42. HttpContext.Current=this.Context;  
  43. ActionResultactionResult=this.Controller.GetAsyncEndDelegate()(result);  
  44. if(actionResult!=null)  
  45. {  
  46. actionResult.ExecuteResult(this.Controller.ControllerContext);  
  47. }  
  48. }  
  49. finally  
  50. {  
  51. this.ControllerFactory.ReleaseController(this.Controller);  
  52. }  
  53. }  

It is important to save the Current Context in the BeginProcessRequest method. HttpContext. Current is based on CallContext. Once an asynchronous callback HttpContext. Current becomes null, it must be reset. The received AsyncCallback and AsyncState are retained, and the Controller is executed using the ready-made Execute method in the framework. When the Execute method returns, the call process of the entire Action method is completed, which means that the call result-IAsyncResult and EndDelegate objects have been retained. Therefore, the IAsyncResult object is taken out and returned. For the EndProcessRequest method, retrieve the EndDelegate saved in the BeginProcessRequest method, call it, and execute the obtained ActionResult again.

The above Code only involves the logic in general circumstances, and the complete code will also include the processing of Action methods in special circumstances such as being terminated or replaced by a Filter. In addition, exceptions must be properly handled in both BeginProcessRequest and EndProcessRequest, so that the Controller Factory can release Controller objects in a timely manner.

If this solution has no defects, I believe it has been put into ASP. net mvc 1.0, and I will not extend it here. The current solution has at least the following shortcomings:

The APM mode in. NET is not strictly followed. Although the function is not affected, it is always a pity.

Because of the ready-made functions in the framework, all filters can only run on the BeginXxx method.

Because the execution of the EndXxx method and the final ActionResult does not support Filter, if an exception is thrown during this process, the exception processing function recommended by ASP. net mvc cannot be entered.

According to Roadmap of ASP. net mvc Framework, asynchronous Action will be supported in Versions later than ASP. net mvc Framework 1.0. I believe that all of the above defects can be compensated at that time. However, this requires a lot of work, which can only be handed over to the ASP. net mvc team for implementation. In fact, you can now find the content related to asynchronous Action processing in the MvcFutures project of ASP. net mvc source code. It has added many extensions such as IAsyncController, AsyncController, IAsyncActionInvoker, and AsyncControllerActionInvoker. Although they all "inherit" existing classes, they are similar to my previous judgment. For example, AsyncControllerActionInvoker has almost completely re-implemented various functions in ActionInvoker-I have not carefully read the code, therefore, it is impossible to determine whether the design is good, just hope it can be like ASP. net mvc itself is as simple and elegant.

I plan to add Filter support for the EndXxx method of the current Code. I need to carefully read the ASP. NET MVC source code to find a solution. It is expected that ASP. net mvc will be a better alternative to supporting asynchronous actions.

  1. AsyncState parameter of ASP. NET
  2. ASP. net mvc executes asynchronous Action
  3. Overview ASP. net mvc Framework
  4. Use the UpdataModel method in ASP. NET MVC
  5. ASP. net mvc Action Method

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.