一. 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. audio

    // media.cpp : 定义控制台应用程序的入口点. // https://wenku.baidu.com/view/e910c474c5da50e2524d7fb4.html https:// ...

  2. JDK内置工具使用(jps、jstack、jmap、jstat)

    一.JPS 1.jps -lvm:用于查看当前机器上已装载的jvm 二.jstackjstack命令主要用来查看Java线程的调用堆栈的,可以用来分析线程问题(如死锁) 1.jstack -l pid ...

  3. FineUI十周年纪念版即将发布(基于像素的响应式布局,独此一家)!

    [新版预报]FineUI十周年纪念版(v5.0.0)即将于2018-04-23发布! 官网示例已更新:http://pro.fineui.com/ 特别助攻:基于像素的响应式布局,FineUI独家秘笈 ...

  4. js中的枚举

    在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的.可枚举性决定了这个属性能否被for…in查找遍历到. js中基本包装类型的原型属性是不可枚举的 ...

  5. Python 中关于 round 函数的坑

    round函数很简单(而且不需要引入math模块),对浮点数进行近似取值,保留几位小数. 比如 # -*- coding: UTF-8 -*- r1=round(12.12345,3) r2=roun ...

  6. 基本环境安装: Centos7+Java+Hadoop+Spark+HBase+ES+Azkaban

    1.  安装VM14的方法在 人工智能标签中的<跨平台踩的大坑有提到> 2. CentOS分区设置: /boot:1024M,标准分区格式创建. swap:4096M,标准分区格式创建. ...

  7. Windows 通过批处理自动执行 linux服务器上面命令的办法

    1. 使用putty 下载地址 https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html 直接使用 exe版本就可以 https:/ ...

  8. Callable,Future和FutureTask详解

    1.Callable和Runnable 看Callable接口: public interface Callable<V> { /** * Computes a result, or th ...

  9. SUCTF 2016 : dMd

    这个题可以说是比较坑了(还不是我很弱...) Linux跑一下: 要输密码 ida打开看看: int __cdecl main(int argc, const char **argv, const c ...

  10. python 条件分支与循环

    一.if判断: 语法一: if 条件: # 条件成立时执行的子代码块 代码1 代码2 代码3 示例: sex='female' age=18 is_beautiful=True if sex == ' ...