1.前提

熟练掌握Task并行编程。

2.用Task并行解释async和await异步

因为控制台有多线程操作的优化,因此这里选择winform来做示例。

测试代码如下所示:

有三个textbox,一个button

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; namespace TestAsyncAwait
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void Button1_Click(object sender, EventArgs e)
{
TestAsync(); textBox3.Text = "333";
} private async void TestAsync()
{
//Thread.Sleep(5000);//依然阻塞 await Task.Run(() =>
{
Thread.Sleep(2000); this.Invoke((EventHandler)delegate { textBox1.Text = "1"; }); Thread.Sleep(2000); }); this.Invoke((EventHandler)delegate { textBox2.Text = "22"; });
} }
}

显示的顺序是:333,1,22

如果在设置textbox显示内容之前,通过Thread.CurrentThread.ManagedThreadId属性来获取当前线程ID。

可以得到textbox3所在为主线程,await之前也在主线程,await中和await后为新线程,这也是为什么在textbox1和textbox2的text加上invoke的原因。

简单来时,实际上async和await就是表示,遇到await之后,函数直接返回,然后剩下的部分等同于在一个新线程中运行。

使用Task并行编程的解释代码如下,将button按钮的click事件与TestAsync函数统一成TestTask函数

        private void TestTask()
{
Task.Run(() =>
{
Task task = Task.Run(() =>
{
Thread.Sleep(2000); this.Invoke((EventHandler)delegate { textBox1.Text = "1"; }); Thread.Sleep(2000);
}); Task.WaitAll(task); this.Invoke((EventHandler)delegate { textBox2.Text = "22"; });
}); textBox3.Text = "333";
}

当然,上述代码也不完全等价async和await,只不过在实现功能上来说,没有差别。

具体的差别表现为,waitall之前的线程与waitall之后所在线程不在同一个线程。这个差别也揭示了async和await的另外一个优势,那就是节约线程,内部实现了线程池优化。

3.总结

如果你懂得Task并行编程或者Thread多线程编程,其实async和await的原理是不难的,没有什么神乎其神的操作。

async和await作为C#异步编程的语法糖,具有无可匹敌的优势,但是很多时候很多人不能理解用法,相比较而言直接使用Task并行编程会更加易懂。

我的建议是,如果是新项目可以使用async和await,让自己的代码更简洁;如果是老项目维护,建议还是使用Task的方式维护,容易读懂。

彻底搞懂C#异步编程 async和await的原理的更多相关文章

  1. .NET4.5 异步编程 async和await

    msdn介绍:https://msdn.microsoft.com/zh-cn/library/hh191443.aspx 其实很简单,标记了async的方法为异步方法,从方法的左大括号开始同步执行, ...

  2. C#异步编程(async and await)及异步方法同步调用

    1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库=异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某个操作时,应用程序可在异步方 ...

  3. 异步编程- async和await

    使用目的 避免阻塞主线程 提高程序响应能力 C#中使用 C# 中的 Async 和 Await 关键字是异步编程的核心. 疑惑 The async and await keywords don't c ...

  4. C#中的异步编程Async 和 Await

    谈到C#中的异步编程,离不开Async和Await关键字 谈到异步编程,首先我们就要明白到底什么是异步编程. 平时我们的编程一般都是同步编程,所谓同步编程的意思,和我们平时说的同时做几件事情完全不同. ...

  5. .net异步编程async和await的讨论收获

    微软官方描述: C# 5 引入了一种简便方法,即异步编程.此方法利用了 .NET Framework 4.5 及更高版本..NET Core 和 Windows 运行时中的异步支持. 编译器可执行开发 ...

  6. C#异步编程----async和await组合的写法

    微软示例: private async void StartButton_Click(object sender, RoutedEventArgs e) { // ExampleMethodAsync ...

  7. 抓住异步编程async/await语法糖的牛鼻子: SynchronizationContext

    长话短说,本文带大家抓住异步编程async/await语法糖的牛鼻子: SynchronizationContext 引言 C#异步编程语法糖async/await,使开发者很容易就能编写异步代码. ...

  8. 异步编程Async/await关键字

    异步编程Async \await 关键字在各编程语言中的发展(出现)纪实. 时间 语言版本 2012.08.15 C#5.0(VS2012) 2015.09.13 Python 3.5 2016.03 ...

  9. .net 异步编程async & await关键字的思考

    C# 5.0引入了两个关键字 async和await,这两个关键字在很大程度上帮助我们简化了异步编程的实现代码,而且TPL中的task与async和await有很大的关系 思考了一下异步编程中的asy ...

随机推荐

  1. 搭建个人博客,Docsify+Github webhook+JGit解决方案

    一开始博客使用的 Halo,发现问题比较多啊,时不时的莫名其妙主题各种报错,有时候还要升级,麻烦的要死,于是就想弄简单点. 这两天抽空反复倒腾了一遍,不小心还把镜像给尼玛删了,发的文章都没了,痛定思痛 ...

  2. 表达式的动态解析和计算,Flee用起来真香

    前言 在很多项目中经常会出现需要动态解析表达式和计算的场景,比如一些自动审核规则,或者是一些变量的值通过维护的公式在运行过程中动态算出:由于场景需求,都需要比较灵活的配置对应的表达式,然后希望在需要的 ...

  3. markdown常用到的语法

    一.标题 后加文字,几个#代表几级标题,最高为6 ,标准语法一般在#后跟个空格再写文字. 二.分割线 三个或者三个以上的 - 或者 * 三.图片 格式: ![A](B "C") A ...

  4. 一次 Keepalived 高可用的事故,让我重学了一遍它!

    原文首发: 你好,我是悟空. 前言 上次我们遇到了一个 MySQL 故障的事故,这次我又遇到了另外一个奇葩的问题: Keepalived 高可用组件的虚拟 IP 持续漂移,导致 MySQL 主从不断切 ...

  5. python常见的错误提示处理

    python常见的错误有 NameError变量名错误 IndentationError代码缩进错误 AttributeError对象属性错误 TypeError类型错误 IOError输入输出错误 ...

  6. typescript+webpack构建一个js库

    依赖说明 入口文件 tsconfig配置 webpack配置文件 webpack入口文件配置 webpack为typescript和less文件配置各自的loader webpack的output配置 ...

  7. linux服务配置IP或者说可以远程连接

    切换目录 cd /etc/sysconfig/network-scripts ls查看当前目录下的东西 找到ipcfg- 开头的,而且不是iocfg-lo,而上图就是那个ifcfg-ens33. 则进 ...

  8. System.Web.Mvc 找到的程序集清单定义与程序集引用不匹配

    System.IO.FileLoadException: 未能加载文件或程序集"System.Web.Mvc, Version=5.0.0.0, Culture=neutral, Publi ...

  9. Centos7安装最新docker

    Centos7安装最新docker(root身份运行) 环境查看 CentOS 需要7版本以上,内核最好3.10以上 1.查看Linux版本:rpm -q centos-release 2.查看内核版 ...

  10. python 执行需要管理员权限的命令(Windows)

    由于Windows存在管理员权限限制,执行需管理员权限的命令时会出错, 有两种方案, 1.采用python调用vbs文件,vbs调用bat文件 2.采用提供弹出用户管理员权限方式让用户确认 1.采用p ...