MVC – Task-based Asynchronous Pattern (TAP) – Async Controller and SessionLess Controller

In async programming, there are 3 different models for different scenarios :

  • Asynchronous Programming Model – APM
  • Task Based Asynchronous Programming Model – TAPM
  • Evented Asynchronous Programming Model – EAPM

We can use all models in .net framework. It provides related libraries in their own namespaces. The Task-based Asynchronous Pattern (TAP) is based on System.Threading.Tasks.Task and System.Threading.Tasks.Task<TResult> types in the System.Threading.Tasks namespaces.

When we’re developing web application, if we need to develop async applications on web side, we can use this libraries to reflect async behavior. For Instance, if we want to communicate external services or channels at the same time, we might use async controller to avoid operation blocks. When we’re reflecting this behavior in an application, We should think tasks in action level. I mean, surely according to our scenario, if we seperate all actions as different tasks, it can be more useful and manageble.

In .Net Framework MVC Applications, We can use Async Controllers and async actions. For instance please check code below :

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public class HomeController : AsyncController
    {
        public NorthwindEntities NorthwindContext { get; set; }
        public HomeController()
        {
            NorthwindContext = new NorthwindEntities();
        }
        public async Task<ActionResult> Index()
        {
            var indexViewModel = new IndexViewModel();
 
            Stopwatch stopwatch = new Stopwatch();
 
            stopwatch.Start();
            indexViewModel.Categories = await Categories();
            indexViewModel.Shippers = await Shippers();
            indexViewModel.Currencies = await Currencies();
            stopwatch.Stop();
 
            indexViewModel.TotalTime = stopwatch.Elapsed;
 
            return View(indexViewModel);
        }
 
        public async Task<List<SelectListItem>> Shippers()
        {
            var shippers = await NorthwindContext.Shippers.Select(x => new SelectListItem()
            {
                Text = x.CompanyName,
                Value = x.ShipperID.ToString()
            }).ToListAsync();
 
            return shippers;
        }
 
        public async Task<List<SelectListItem>> Categories()
        {
            var shippers = await NorthwindContext.Categories.Select(x => new SelectListItem()
            {
                Text = x.CategoryName,
                Value = x.CategoryID.ToString()
            }).ToListAsync();
 
            return shippers;
        }
 
        public async Task<string> Currencies()
        {
            WebClient client = new WebClient();
 
            var exchange = await client.DownloadStringTaskAsync("http://www.tcmb.gov.tr/kurlar/today.xml");
 
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(exchange);
 
            string USDSELL = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='USD']/BanknoteSelling").InnerXml;
 
            string USDBUY = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='USD']/BanknoteBuying").InnerXml;
 
            return $"USD Banknote Selling :{USDSELL} - Banknote Buying :{USDBUY}";
        }
    }
 
    public class IndexViewModel
    {
        public TimeSpan TotalTime { get; set; }
        public List<SelectListItem> Categories { get; set; }
        public List<SelectListItem> Shippers { get; set; }
        public string Currencies { get; set; }
    }

And also, if you need to run multiple requests concurrently, use SessionLess controller :

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
[SessionState(SessionStateBehavior.Disabled)]
    public class HomeController : Controller
    {
        public NorthwindEntities NorthwindContext { get; set; }
        public HomeController()
        {
            NorthwindContext = new NorthwindEntities();
        }
        public async Task<ActionResult> Index()
        {
            var indexViewModel = new IndexViewModel();
 
            Stopwatch stopwatch = new Stopwatch();
 
            stopwatch.Start();
            indexViewModel.Categories = await Categories();
            indexViewModel.Shippers = await Shippers();
            indexViewModel.Currencies = await Currencies();
            stopwatch.Stop();
 
            indexViewModel.TotalTime = stopwatch.Elapsed;
 
            return View(indexViewModel);
        }
 
        public async Task<List<SelectListItem>> Shippers()
        {
            var shippers = await NorthwindContext.Shippers.Select(x => new SelectListItem()
            {
                Text = x.CompanyName,
                Value = x.ShipperID.ToString()
            }).ToListAsync();
 
            return shippers;
        }
 
        public async Task<List<SelectListItem>> Categories()
        {
            var shippers = await NorthwindContext.Categories.Select(x => new SelectListItem()
            {
                Text = x.CategoryName,
                Value = x.CategoryID.ToString()
            }).ToListAsync();
 
            return shippers;
        }
 
        public async Task<string> Currencies()
        {
            WebClient client = new WebClient();
 
            var exchange = await client.DownloadStringTaskAsync("http://www.tcmb.gov.tr/kurlar/today.xml");
 
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(exchange);
 
            string USDSELL = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='USD']/BanknoteSelling").InnerXml;
 
            string USDBUY = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='USD']/BanknoteBuying").InnerXml;
 
            return $"USD Banknote Selling :{USDSELL} - Banknote Buying :{USDBUY}";
        }
    }
 
    public class IndexViewModel
    {
        public TimeSpan TotalTime { get; set; }
        public List<SelectListItem> Categories { get; set; }
        public List<SelectListItem> Shippers { get; set; }
        public string Currencies { get; set; }
    }

AST

This entry was posted in .Net FrameworkASP.NetDesign PatternsMVCServer Side Web Programming,Web Programming and tagged asyncasynchronous operationscontrollermvc 5sessionlesstaptask based asynchronous pattern on July 4, 2016.

基于异步的MVC webAPI控制器的更多相关文章

  1. SlickOne -- 基于Dapper, Mvc和WebAPI 的快速开发框架

    前言:在两年前,项目组推出了基于Dapper,Mvc和WebApi的快速开发框架,随着后续Slickflow产品的实践和应用,今再次对SlickOne项目做以回顾和总结.其目的是精简,持续改进,保持重 ...

  2. SlickOne敏捷开发框架介绍(一) -- 基于Dapper, Mvc和WebAPI 的快速开发框架

    前言:在两年前(最初发布时间:2013年1月9日(csdn),当前文章时间2015年11月10日),项目组推出了基于Dapper,Mvc和WebApi的快速开发框架,随着后续Slickflow产品的实 ...

  3. C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理

    C#编译器优化那点事   使用C#编写程序,给最终用户的程序,是需要使用release配置的,而release配置和debug配置,有一个关键区别,就是release的编译器优化默认是启用的.优化代码 ...

  4. Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World。

    系列目录 1.Taurus.MVC WebAPI  入门开发教程1:框架下载环境配置与运行. 2.Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World. 3.Tau ...

  5. Taurus.MVC WebAPI 入门开发教程4:控制器方法及参数定义、获取及基础校验属性【Require】。

    系列目录 1.Taurus.MVC WebAPI  入门开发教程1:框架下载环境配置与运行. 2.Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World. 3.Tau ...

  6. Taurus.MVC WebAPI 入门开发教程5:控制器安全校验属性【HttpGet、HttpPost】【Ack】【Token】【MicroService】。

    系列目录 1.Taurus.MVC WebAPI  入门开发教程1:框架下载环境配置与运行. 2.Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World. 3.Tau ...

  7. Taurus.MVC WebAPI 入门开发教程6:全局控制器DefaultController与全局事件。

    系列目录 1.Taurus.MVC WebAPI  入门开发教程1:框架下载环境配置与运行. 2.Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World. 3.Tau ...

  8. MVC WebApi 用户验证 (2)

    构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(66)-MVC WebApi 用户验证 (2)   前言: 构建ASP.NET MVC5+EF6+E ...

  9. 构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(66)-MVC WebApi 用户验证 (2)

    前言: 构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(65)-MVC WebApi 用户验证 (1) 回顾上一节,我们利用webapi简单的登录并 ...

随机推荐

  1. Razor 在JS中嵌入后台变量

    HTML 中定义全局变量 @{ int CurrentUserId =ViewBag.CurrentUserId; } JS中取值方式var CurrentUserId = parseInt(@Htm ...

  2. HDU_2045——RPG问题,递推

    Problem Description 人称“AC女之杀手”的超级偶像LELE最近忽然玩起了深沉,这可急坏了众多“Cole”(LELE的粉丝,即"可乐"),经过多方打探,某资深Co ...

  3. 【转】YUV值对应的颜色

    版权声明:本文为博主原创文章,未经博主允许不得转载.欢迎大家积极评论,博主会一一答复! 最近有人在网上问我,YUV的值对应的颜色是如何的 下面给出YUV值对应的颜色关系 256张图512x512,每张 ...

  4. apache shiro内置过滤器 标签 注解

    内置过滤器 anon(匿名)  org.apache.shiro.web.filter.authc.AnonymousFilter authc(身份验证)       org.apache.shiro ...

  5. effective C++: 5实现

    五.实现 大多数情况下,适当提出拟的类定义以及函数声明,是花费最多心力的两件事.尽管如此,还是有很多东西需要小心:太快定义变量可能造成效率上的拖延:过度使用转型(casts)可能导致代码变慢又难维护, ...

  6. hibernate 一对多双向关联 详解

    一.解析: 1.  一对多双向关联也就是说,在加载班级时,能够知道这个班级所有的学生. 同时,在加载学生时,也能够知道这个学生所在的班级. 2.我们知道,一对多关联映射和多对一关联映射是一样的,都是在 ...

  7. 【创业积累】如何快速开发出一个高质量的APP

    [起] 今早,一个技术群里有人想快速做出一个app,然后询问技术方案,大概是这样, 拿到了200w投资,期望花20w两个月先做出一个app,包括ios,android, 先,呵呵,一下, 大概预估了一 ...

  8. 获取当前位置信息-ios

    locationManager= [[CLLocationManager alloc] init];//位置管理器 locationManager.desiredAccuracy = kCLLocat ...

  9. Redis源代码分析-内存数据结构intset

    这次研究了一下intset.研究的过程中,一度看不下过去,可是还是咬牙挺过来了.看懂了也就是那么回事.静下心来,切莫浮躁 Redis为了追求高效,在存储下做了非常多的优化,像intset就是作者为了节 ...

  10. 【性能优化】优化笔记之一:图像RGB与YUV转换优化

    本文主要介绍如何优化您自己的CODE,实现软件的加速.我们一个图象模式识别的项目,需要将RGB格式的彩色图像先转换成黑白图像.图像转换的公式如下: Y = 0.299 * R + 0.587 * G ...