本文重点介绍的是.NET Framework4.5 推出的异步编程方案  async await

请先看个5分钟的微软演示的视频:
视频地址: https://channel9.msdn.com/Blogs/ASP-NET-Site-Videos/async-and-await

网络上已经有很多文章介绍了这个技术点的应用方式,但是举的例子都是.NET 自带提供的系统异步方法

所以有些同学就看不大懂,如果是非系统自带的,如何实现异步。

实际上,有时候一点就能通,把异步的本质了解明白了,也就懂了。

异步编程的本质就是  新开任务线程来处理

这个如何理解呢,请看下文介绍异步编程发展史

static void Main(){

    new Thread(Go).Start();  // .NET 1.0开始就有的
Task.Factory.StartNew(Go); // .NET 4.0 引入了 TPL
Task.Run(new Action(Go)); // .NET 4.5 新增了一个Run的方法
}

这里大家不难看出,.NET 4.5之后引入了 Task.Run方法,实际上呢,异步编程就是通过这个实现的。

了解线程的人也知道,新开一个线程来处理事务,这个很常见,但是在以往,是没办法接收线程里面返回的值的。

所以这时候就该 await 出场了

await,从字面意思,不难理解,就是等待的意思。

执行await的方法必须是async修饰的,并且是Task的类型。 异步执行后,返回的信息存储在result属性中。

但并非主进程就会卡在await行的代码上,执行到await方法之后,主线程继续往下执行,无需等待新的线程执行完再继续。

当需要用到新线程返回的result结果时,此时主进程才会等待新线程执行完并返回内容。

也就会说,若无需用到新线程返回的结果,那么主进程不会等待。

async 和await呢,返回类型就3种,void,Task,Task<TResult>

1、void

如果在触发后,你懒得管,请使用 void。

void 返回类型主要用在事件处理程序中,一种称为“fire and forget”(触发并忘记)的活动的方法。除了它之外,我们都应该尽可能是用 Task,作为我们异步方法的返回值。

返回 void,意味着不能 await 该异步方法,即可能出现线程阻塞,并且也无法获取 exception,抛出的异常,通常这些异常会导致我们的程序失败,如果你使用的是 Task 和 Task<Result>,catch 到的异常会包装在属性里面,调用方法就可以从中获取异常信息,并选择正确的处理方式。

2、Task
你如果只是想知道执行的状态,而不需要一个具体的返回结果时,请使用 Task
与void对比呢,是Task可以使用await进行等待新线程执行完毕。而void不需要等待。

3、Task<TResult> 
当你添加 async 关键字后,需要返回一个将用于后续操作的对象,请使用 Task<TResult>。

主要有两种方式获取结果值,一个是使用 Result 属性,一个是使用 await。他们的区别在于:如果你使用的是 Result,它带有阻塞性。即在任务完成之前进行访问读取它,当前处于活动状态的线程都会出现阻塞的情形,一直到结果值可用。所以,在绝大多数情况下,除非你有绝对的理由告诉自己,否则都应该使用 await,而不是属性 Result 来读取结果值。

下面我们直接看一些代码就懂了:

        /// <summary>
/// 添加多条
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public virtual bool Add(IEnumerable<T> list)
{
CreateDataBase();//创建数据库连接
foreach (T t in list)
{
this.Add(t);
}
return true;
} public virtual async Task<bool> AddAsync(IEnumerable<T> list)
{
return await Task.Run(() => this.Add(list));
}

正常情况下,我们约定,异步的方法名均以Async结尾。

以下是服务层调用

/// <summary>
/// 日志的json格式字符串 包含 title,url,level,descript
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public async Task<bool> AddAsync(string content)
{
using (var mongoDbContext = new Log.DAL.DbContext())
{
if (!string.IsNullOrWhiteSpace(content))
{
Log.Model.Record model = Newtonsoft.Json.JsonConvert.DeserializeObject<Log.Model.Record>(content);
model.AddTime = DateTime.Now;
var result = await mongoDbContext.Record.AddAsync(model);
return result;
}
else
{
return false;
}
}
}

再接着,进行控制器中的调用

  public async Task<ActionResult> Add(string content)
{
var flag = await new Log.Service.RecordService().AddAsync(content); ;
return View();
}

下面的代码呢,我们演示一下什么时候需要用到result属性

//不需要,因为用了await  

public async Task<ActionResult> Detail(int id)
{
var model = await new DbContext().Record.FirstOrDefaultAsync(m => m.ID == id);
return View(model);
} //需要
public async Task<ActionResult> Detail(int id)
{
var model = new DbContext().Record.FirstOrDefaultAsync(m => m.ID == id).Result;
return View(model);
}

这样,我们异步编程就讲解完了。本文主要是讲解异步是实质,学习这个需要异步有一定的学习和了解。

总结:

  • 当你添加 async 关键字后,需要返回一个将用于后续操作的对象,请使用 Task<TResult>;

  • 你如果只是想知道执行的状态,而不需要知道具体的返回结果时,请使用 Task;

  • 如果在触发后,你懒得管,请使用 void。

  • 请尽量优先使用 Task<TResult> 和 Task 作为异步方法的返回类型。
  • 用了await,方法必须使用async来修饰。

参考文章:http://www.cnblogs.com/jesse2013/p/async-and-await.html  这里介绍了异步的详细发展史。

ASP.NET 异步编程之Async await的更多相关文章

  1. 异步编程之Async,Await和ConfigureAwait的关系

    在.NET Framework 4.5中,async / await关键字已添加到该版本中,简化多线程操作,以使异步编程更易于使用.为了最大化利用资源而不挂起UI,你应该尽可能地尝试使用异步编程.虽然 ...

  2. ASP.NET Core Web 应用程序系列(四)- ASP.NET Core 异步编程之async await

    PS:异步编程的本质就是新开任务线程来处理. 约定:异步的方法名均以Async结尾. 实际上呢,异步编程就是通过Task.Run()来实现的. 了解线程的人都知道,新开一个线程来处理事务这个很常见,但 ...

  3. 初探asp.net异步编程之await

    终于毕业了,也顺利进入一家期望的旅游互联网公司.27号入职.放肆了一个多月没写代码,好方啊. 另外一下观点均主要针对于await. 请先看这段话,来自async in C# 5.0.  接下来几个月的 ...

  4. .Net异步编程之Async与Await的使用

    参考教程:http://www.cnblogs.com/x-xk/archive/2013/06/05/3118005.html http://www.cnblogs.com/tdws/p/56790 ...

  5. net异步编程之await

    net异步编程之await 初探asp.net异步编程之await   终于毕业了,也顺利进入一家期望的旅游互联网公司.27号入职.放肆了一个多月没写代码,好方啊. 另外一下观点均主要针对于await ...

  6. python异步编程之asyncio

    python异步编程之asyncio   前言:python由于GIL(全局锁)的存在,不能发挥多核的优势,其性能一直饱受诟病.然而在IO密集型的网络编程里,异步处理比同步处理能提升成百上千倍的效率, ...

  7. 异步编程之Generator(1)——领略魅力

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

  8. 异步编程之Promise(3):拓展进阶

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

  9. 异步编程之Promise(2):探究原理

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

随机推荐

  1. linuxIP地址配置字段说明

    虚拟机网络适配器改成桥接 vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 设备名称 BOOTPROTO=dhcp /static 自动 ...

  2. Linux操作系统的日志管理之rsyslog实战案例

    Linux操作系统的日志管理之rsyslog实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.日志介绍 1>.什么是日志 历史事件: 时间,地点,人物,事件 日志级 ...

  3. matplotlib 中的 colors 和 cmaps

    matplotlib 中的 148 种颜色 matplotlib 中的 160 种颜色映射 1.matplotlib中的 148 种颜色 import matplotlib as plm import ...

  4. djabgo 中间件

    1.中间件是发生在request和response 之间,都会经过中间键, 上述截图中的中间件都是django中的,我们也可以自己定义一个中间件,我们可以自己写一个类,但是必须继承Middleware ...

  5. USACO Cow Frisbee Team

    洛谷 P2946 [USACO09MAR]牛飞盘队Cow Frisbee Team 洛谷传送门 JDOJ 2632: USACO 2009 Mar Silver 2.Cow Frisbee Team ...

  6. 【Excel】IF函数

    判断条件: 一版判断:1>2大于   1<2小于   1=2等于   1<>2不等于  1>=2 1<=2 交集:AND() 并集:OR() 多条件:以后补

  7. es6 Class类的使用

    es6新增了一种定义对象实例的方法,使用class关键字定义类,与class相关的知识点也逐步火热起来,但是部分理解起来相对抽象,简单对class相关的知识点进行总结,更好的使用class. 关于类有 ...

  8. ESA2GJK1DH1K基础篇: STM32+Wi-Fi(AT指令版)实现MQTT源码讲解

    前言 注: 本程序发送心跳包,发送温湿度,返回控制数据这三个发送是单独的,有可能凑到一起发. 由于本身程序就是复杂性的程序,所以这节程序没有使用中断发送,没有使用环形队列发送,为了避免多条消息可能凑到 ...

  9. 不了解这12个语法糖,别说你会Java!

    阅读本文大概需要 10 分钟. 作者:Hollis 本文从 Java 编译原理角度,深入字节码及 class 文件,抽丝剥茧,了解 Java 中的语法糖原理及用法,帮助大家在学会如何使用 Java 语 ...

  10. 【K8S】helm chart多环境部署最佳实践-示例

    Chart.yaml apiVersion: v1 appVersion: "1.0" description: A Helm chart for Kubernetes name: ...