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. DPDK2.1开发者手册4-7

    Mempool Labrary 一个内存池(memory pool)就是固定大小对象的分配器.在dpdk中,它是通过名字来标示唯一性的,且使用环形队列来保存没有使用的空闲对象.它提供了一些可选项服务例 ...

  2. sqlserver2012关于allwayson和复制结合起来的做法以及需要注意的问题

    allwayson的自动故障转移需要它对应的windows故障转移群集有仲裁设置,这样相当于三台以上的服务器做allwayson才比较合适   1.首先安装sqlserver的时候需要勾选上“复制” ...

  3. split

    import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; /** * 解析知网文章的页面 ...

  4. Java[2] 分布式服务架构之java远程调用技术浅析(转http://www.uml.org.cn/zjjs/201208011.asp)

    转自:http://www.uml.org.cn/zjjs/201208011.asp 在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如: ...

  5. android开发常用组件(库)推荐

    版本兼容:官方 support 全家桶 网络请求:Android-Async-Http.Retrofit.OkHttp.Volley图片加载:Glide 和 Universal-Image-Loade ...

  6. (转)Apple Push Notification Services in iOS 6 Tutorial: Part 2/2

    转自:http://www.raywenderlich.com/32963/apple-push-notification-services-in-ios-6-tutorial-part-2 Upda ...

  7. Eclipse集成PDT+XDebug调试PHP脚本 https://svn.jcxsoftware.com/node?page=5 [转]

    win7+xampp-win32-1.8.2-2-VC9+eclipse-jee-indigo-SR2-win32-x86_64.zip http://pjdong1990.iteye.com/blo ...

  8. SQL通用函数-nvl-nvl2 -nvlif-nullif-coalesce-decode-case

    通用函数适用于任何类型数据(包括空值),一般用于实现空值处理.条件运算和多路分支结果,下面介绍其中常用的几种: nvl(exp1, exp2) 函数nvl(exp1, exp2)用于将空值转换为指定的 ...

  9. Win7_x64下卸载Oracle11g

    Windows下Oracle11g卸载顺序1.计算机管理-->服务和应用程序-->停止所有Oracle相关服务2.运行D:\app\Administrator\product\11.2.0 ...

  10. 网页CSS

    CSS 样式表,(分三类:内联.内嵌.外部) 1,内联, 直接作于于 元素 例:   <p style="font-size:14px;"> 2,内嵌 作用于网页 首先 ...