本文重点介绍的是.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. 用 np.logspace() 创建等比数列

    np.logspace( start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0, ) Docstring: Return ...

  2. No qualifying bean of type 'com.chinanums.agent.operation.service.component.OperationPageComponent' available:

    java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.conte ...

  3. hdu1873-看病要排队-(结构体优先队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=1873 #include<stdio.h> #include<iostream> #inc ...

  4. zzulioj - 2617 体检

    题目链接: http://acm.zzuli.edu.cn/problem.php?id=2617 题目描述: VX玩了这么多游戏以后,感觉自己身体素质和智商都有所下降,所以决定去医院体检一下.已知V ...

  5. Pandas | 11 字符串函数

    在本章中,我们将使用基本系列/索引来讨论字符串操作.在随后的章节中,将学习如何将这些字符串函数应用于数据帧(DataFrame). Pandas提供了一组字符串函数,可以方便地对字符串数据进行操作. ...

  6. [无效]网络流之Edmond-Karp算法

    // 此博文为迁移而来,写于2015年2月2日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vr12.html   UP ...

  7. 【字符串】 manacher算法

    Algorithm Task 给定一个字符串,求其最长回文子串 Limitations 要求时空复杂度均为线性且与字符集大小无关. Solution 考虑枚举回文串的对称轴,将其对应的最长回文子串长度 ...

  8. Kafka问题总结

    kafka问题总结 kafka如何保证数据可靠性和数据一致性 Kafka Rebalance机制分析 Kafka的用途有哪些?使用场景如何? Kafka中的ISR.AR又代表什么?ISR的伸缩又指什么 ...

  9. Mac下Sublime Text常用插件

    Mac下Sublime Text常用插件 SideBarEnhancements 右键菜单增强插件 BracketHighlighter 括号.引号.标签高亮插件 Pretty JSON JSON美化 ...

  10. 关于Vue中props的详解

    看一下官方文档: 组件实例的作用域是孤立的.这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据.父组件的数据需要通过 prop 才能下发到子组件中. 也就是props是子组件访问父组件数 ...