Aspnet MVC 异步调用

一个简图来描述下Aspnet MVC下的异步调用

  { request }
  /    \/
-------ISS------- > work thread
  |        |       \  route - aysn controller
  |          |         \ [invoke] clr thread pool
  |         /
  |        /
  |       /  complete -> asyncManager
  |      /
  |------asyncManager 

从简图可以了解:
用户发送请求,服务器路由到控制器,控制器到action,action内部通过线程池调用新线程执行request,然后将数据返回给用户。

该简图涉及到controller的一个属性AsyncManager
asyncManagerde的作用主要体现在两点:
1. 标识异步的开始和结束,通 过  AsyncManager.OutstandingOperations.Increment/OutstandingOperations.Decrement
2. 在执行线程到结束回调过程中的参数传递 通过AsyncManager.Parameters (类型为字典,传递参数时候需要注意Key需要跟结果参数回调的参数名一致)。

asyncManager在异步调用中并不是必须的。

异步虽好,但并不是所有的场合都是适合的,一般来说如果没有长耗时和分布的需求情况下,异步是没要的

在aspnet mvc中实现异步操作有三种方式:

1.通过异步控制器AsyncController
  自定义控制器通过继承AsyncController,在内部定义XXXAsync/XXXCompleted格式的action,例如:

public void IndexAsync() { }
public ActionResult IndexCompleted(string parameter);

//其中indexCompleted中的参数parameter
//通过AsyncManager.Parameters ["parameter‘] = XX传递
//参数名和KEY要保持一致性

Async和completed定义总是成对出现了,async定义的方法用于执行异步操作,而completed定义的方法用于返回结果.

通过XXasync和XXcompeleted定义的方法,ASPNET MVC在调用时候并不是以异步的方式调用,所以真正的工作还是需要我们自己async中定义异步操作.一个简单的例子:

    public class CustomAsyncController: AsyncController
    {
        public void IndexAsync() {
            //increment不写参数情况默认计数为1
            //如果存在多个task需要添加相应的计数值,以保证结果能正确的返回
            AsyncManager.OutstandingOperations.Increment();
            Task.Factory.StartNew(() =>
           {
               int sum = 0;
               for (int i = 0; i < 10000000; i++) { sum += i; }

               //传递参数给XXXCompleted
               AsyncManager.Parameters["sum"] = sum;

               //end
               AsyncManager.OutstandingOperations.Decrement();//多个任务要多次调用,调用次数一般等于increment中设置的计数
           });

        }
        public ActionResult IndexCompleted(string sum)
        {
            return Content(sum.ToString());
        }
    }

2.通过async和await关键字

async/await关键字用于标识异步操作,我们用一个简单的例子来演示async/await的使用

a.例子我们先定义个webapi,用于返回用户信息

b.通过服务类,异步调用改用webapi接口返回用户信息

c.控制器调用服务类返回数据结果

    public class UserController : ApiController
    {
        private static UserRepository _respository = new UserRepository();

        [System.Web.Http.HttpGet]
        public IList<UserModel> GetAll()
        {
            return _respository.GetAll();
        }
    }
   public class UserService
    {
        private static UserService instance = null;
        public static UserService Instance
        {
            get
            {
                if (instance == null)
                    instance = new UserService();

                return instance;
            }
        }
        public async Task<IList<UserModel>> GetUsersAsync( CancellationToken token =default(CancellationToken))
        {
            var uri = "http://localhost:3541/api/user/getall";
            using(HttpClient client  = new HttpClient())
            {
                var response = await client.GetAsync(uri);
                return await response.Content.ReadAsAsync<IList<UserModel>>();
            }
        }
    }
    public class CustomController : Controller
    {
       public async Task<ActionResult> Index()
        {
             IList < UserModel > models = await UserService.Instance.GetUsersAsync();

            return Json(models,JsonRequestBehavior.AllowGet);
        }
    }

3.直接通过返回task实现异步

  最简单最直接的一种方式了

    public class HomeController : AsyncController
    {
        public Task<ActionResult> Index()
        {
            return Task.Factory.StartNew(() =>
           {
               return new List<UserModel>
               {
                    new UserModel {Name ="visonme" },
                    new UserModel {Name = "visonme2" }
               };
           }).ContinueWith<ActionResult>((task) =>
           {
               return Json(task.Result, JsonRequestBehavior.AllowGet);
           });
        }
    }


Aspnet MVC 异步调用

时间: 2024-10-14 11:23:42

Aspnet MVC 异步调用的相关文章

mvc路由引起异步调用web服务的问题

从一篇blog得知使用脚本可以异步调用Web服务,觉得很新鲜,因为自己很少用到Web服务,所以决定写一写看看什么效果. 首先在UI项目(我使用的是MVC4.0)里创建一个Web服务. 添加Web服务后,默认有一个HelloWorld方法.调用该方法有两种形式,一是服务端通过实例化对象调用,二是前端脚本异步 调用.代码分别是: 1.服务端调用 public ActionResult Index() { WebService1 ws = new WebService1(); var str = ws

【ASP.Net MVC】AspNet Mvc一些总结

AspNet Mvc一些总结 RestaurantReview.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text.RegularExpressions; using System.Web; using System.Web.M

记录学习MVC过程,MVC异步请求(五)

1.基与jquery的异步请求 <script src="~/Scripts/jquery-1.8.2.min.js"></script> <script type="text/javascript"> $(function() { $("#btn_jquery").click(function() { $.ajax({ url: "/Users/Getdata", type: "

AspNet MVC中各种上下文理解

0  前言 AspNet MVC中比较重要的上下文,有如下: 核心的上下文有HttpContext(请求上下文),ControllerContext(控制器上下文) 过滤器有关有五个的上下文ActionExecutingContext,ActionExecutedContext,ResultExecutingContext,ResultExecutedContext,ExceptionContext 视图相关的上下文ViewContext 这些上下文之间的关系如下图所示 说明: 1.Contro

AspNet MVC : 操作/控制器过滤器(action filter)

1.Action Filter Action Filter提供了在执行action/controller前后对请求/响应修改的能力,可以应用于action和控制器上,作用在控制器上将自动被应用到该控制器下所有的action. 常见的应用场景例如: 用户验证授权, 修改view的返回结果,修改response头,日志记录,异常/错误处理等 . AspNet MVC包含四种类型的action filter: a.Auth Filter 验证过滤器,实现IAuthorizationFilter,用于针

客户端的异步调用

C#客户端的异步操作 阅读目录 开始 示例项目介绍 同步调用服务 异步接口介绍 1. 委托异步调用 2. 使用IAsyncResult接口实现异步调用 3. 基于事件的异步调用模式 4. 创建新线程的异步方式 5. 使用线程池的异步方式 6. 使用BackgroundWorker实现异步调用 客户端的其它代码 各种异步方式的优缺点 异步文件I/O操作 数据库的异步操作 异步设计的使用总结 在Asp.net中使用异步 上篇博客[用Asp.net写自己的服务框架] 我讲述了如何实现自己的服务框架,但

ASP.NET MVC异步验证是如何工作的03,jquery.validate.unobtrusive.js是如何工作的

在上一篇"ASP.NET MVC异步验证是如何工作的02,异步验证表单元素的创建"中了解了ASP.NET异步验证是如何创建表单元素的,本篇体验jquery.validate.unobtrusive.js异步验证的全过程. 在jquery.validate.unobtrusive.js文件的尾部看到了如下的一个调用: $(function () { $jQval.unobtrusive.parse(document); }); 可见,通过把当前页的document对象传给$jQval.u

(转)spring boot注解 [email&#160;protected] 异步调用

原文:http://www.cnblogs.com/azhqiang/p/5609615.html EnableAsync注解的意思是可以异步执行,就是开启多线程的意思.可以标注在方法.类上. 1 @Component 2 public class Task { 3 4 @Async 5 public void doTaskOne() throws Exception { 6 // 同上内容,省略 7 } 8 9 @Async 10 public void doTaskTwo() throws

CXF简单示例(二)之异步调用

在实际使用中,客户端在调用服务时,并不能及时得到响应,比如调用的服务本身是一个耗时费事的活,服务器破死命的跑,也只能在一分钟后才能够返回结果,这时候如果是同步的情况,那么客户端就必须在这里到等上一分钟,啥事不干.这肯定是不能容忍的,光吃饭不干活,再有这么好的事,请告诉我! OK,所以我们需要异步调用. 在这里,先介绍CXF提供的一个工具:WSDL2Java. 我们可以方便的利用它来生成相应的客户端接口,配置什么的脏活累活它都给我们干了,而我们只需要这样直接用就行了. 1. 获得服务的WSDL路径