一. async和await简介

PS:简介

1. async和await这两个关键字是为了简化异步编程模型而诞生的,使的异步编程跟简洁,它本身并不创建新线程,但在该方法内部开启多线程,则另算。

2. 这两个关键字适用于处理一些文件IO操作。

3. 好处:代码简介,把异步的代码写成了同步的形式,提高了开发效率。

 坏处:如果使用同步思维去理解,容易出问题,返回值对不上。

二. 几种用法

情况1:当只有async,没有await时,方法会有个警告,和普通的多线程方法没有什么区别,不存在线程等待的问题。

代码实践:

  private static async void Test1()
{
//主线程执行
Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
//启动新线程完成任务
Task task = Task.Run(() =>
{
Console.WriteLine("子线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep();
Console.WriteLine("子线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
});
//主线程执行
Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
}

代码结果:

情况2:不推荐void返回值,使用Task来代替Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行。

代码实践:

         /// <summary>
/// 不推荐void返回值,使用Task来代替
/// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用。async Void 不行
/// </summary>
private static async void Test2()
{
//主线程执行
Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
//启动新线程完成任务
Task task = Task.Run(() =>
{
Console.WriteLine("子线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep();
Console.WriteLine("子线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
});
await task; //等待子线程执行完毕,方可执行后面的语句
Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
}

代码结果:

情况3:async Task == async void。 区别:Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行。

代码实践:

          /// <summary>
/// 无返回值 async Task == async void
/// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行
/// </summary>
private static async Task Test3()
{
//主线程执行
Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
//启动新线程完成任务
Task task = Task.Run(() =>
{
Console.WriteLine("子线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep();
Console.WriteLine("子线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
});
await task; //等待子线程执行完毕,方可执行后面的语句
Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
}

代码结果:

情况4和情况5:说明要使用子线程中的变量,一定要等子线程执行结束后再使用。

代码实践:

         /// <summary>
/// 带返回值的Task,要使用返回值,一定要等子线程计算完毕才行
/// </summary>
/// <returns></returns>
private static async Task<long> Test4()
{
//主线程执行
Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
long result = ;
//启动新线程完成任务
Task task = Task.Run(() =>
{
for (long i = ; i < ; i++)
{
result += i;
}
});
await task; //等待子线程执行完毕,方可执行后面的语句
Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("result:{0}", result);
return result;
}
         /// <summary>
/// 带返回值的Task,要使用返回值,一定要等子线程计算完毕才行
/// 与情况四形成对比,没有等待,最终结果不准确
/// </summary>
/// <returns></returns>
private static Task<long> Test5()
{
//主线程执行
Console.WriteLine("主线程{0}开始:", Thread.CurrentThread.ManagedThreadId);
long result = ;
//启动新线程完成任务
TaskFactory taskFactory = new TaskFactory();
Task<long> task = taskFactory.StartNew<long>(() =>
{
for (long i = ; i < ; i++)
{
result += i;
}
return ;
});
Console.WriteLine("主线程{0}结束:", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("result:{0}", result);
return task;
}

代码结果:

  以上两种情况,第一种情况含有线程等待的结果为4950,第二个情况么有线程等待,结果不准确(即共享变量竞用问题)。

第十节:利用async和await简化异步编程模式的几种写法的更多相关文章

  1. 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)[msdn.microsoft.com]

    看到Microsoft官方一篇关于异步编程的文章,感觉挺好,不敢独享,分享给大家. 原文地址:https://msdn.microsoft.com/zh-cn/library/hh191443.asp ...

  2. 使用Async和Await进行异步编程(C#版 适用于VS2015)

    你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net F ...

  3. 使用Async和Await进行异步编程(C#版 适用于VS2015) z

    你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net F ...

  4. Async和Await进行异步编程

    使用Async和Await进行异步编程(C#版 适用于VS2015) 你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很 ...

  5. 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单

    一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...

  6. 转:[你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单

    本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单  async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...

  7. [你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单

    本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单  async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...

  8. 四、C# 5.0 新特性——Async和Await使异步编程更简单

    一.引言 .NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就 ...

  9. 【C#复习总结】 Async 和 Await 的异步编程

    谈到异步,必然要说下阻塞,在知乎上看到了网友举的例子非常省动,在这里我引用下. 怎样理解阻塞非阻塞与同步异步的区别? 老张爱喝茶,废话不说,煮开水. 出场人物:老张,水壶两把(普通水壶,简称水壶:会响 ...

随机推荐

  1. Extjs 在Grid单元中格添加Tooltip提示

    Grid 中的单元格添加Tooltip 的效果 Ext.QuickTips.init(); //必须要… columns: [ { text: 'Name', dataIndex: 'name' }, ...

  2. 我的第一个python web开发框架(32)——定制ORM(八)

    写到这里,基本的ORM功能就完成了,不知大家有没有发现,这个ORM每个方法都是在with中执行的,也就是说每个方法都是一个完整的事务,当它执行完成以后也会将事务提交,那么如果我们想要进行一个复杂的事务 ...

  3. 面向对象_new,__eq__,__hash__

    老师博客:http://www.cnblogs.com/Eva-J/articles/7351812.html __new__ __init__是一种初始化的方法 __new__是构建方法,创建一个对 ...

  4. 为什么不建议在 HBase 中使用过多的列族

    我们知道,一张 HBase 表包含一个或多个列族.HBase 的官方文档中关于 HBase 表的列族的个数有两处描述: A typical schema has between 1 and 3 col ...

  5. centos7下kubernetes(13。kubernetes-探讨service IP)

    service cluster IP是一个虚拟IP,是由kubernetes节点上的iptables规则管理的 通过iptables-save | grep 10.105.215.156看到与clus ...

  6. day 13 迭代器、可迭代对象、迭代器对象、生成器、生成器对象、枚举对象

    迭代器大概念 # 迭代器:循环反馈的容器(集合类型)# -- 不同于索引取值,但也可以循环的从容器对象中从前往后逐个返回内部的值​# 优点:不依赖索引,完成取值# 缺点:不能计算长度,不能指定位取值( ...

  7. 19 python初学(os 模块,sys 模块,hashlib 模块)

    os 模块: # _author: lily # _date: 2019/1/13 import os print(os.getcwd()) # 得到当前的工作目录 # print(os.chdir( ...

  8. wxWidgets 和 QT 之间的选择

    (非原创,网络摘抄) 跨平台的C++ GUI工具库很多,可是应用广泛的也就那么几个,Qt.wxWidgets便是其中的翘楚这里把GTK+排除在外,以C实现面向对象,上手相当困难,而且Windows平台 ...

  9. vim美化基本配置

    在home目录中创建一个 .vimrc文件 vim ~/.vimrc 文件基本配置 " 设置当文件被改动时自动载入 set autoread " quickfix模式 autocm ...

  10. mysql 提高一 动态sql 传变量

    1.需求 DELIMITER $$ SECOND STARTS '2018-09-07 08:00:00' ON COMPLETION PRESERVE ENABLE DO BEGIN ) DEFAU ...