await和async简介

  await和async是在C#5中引入,并且在.NetFramewor4.5以及.NetCore中进行了支持。主要是解决性能瓶颈,并且增强系统的响应能力。

msdn关于await以及async运行机理的描述

以上demo详细的描述了使用await时程序的运行机制,需要注意的以下几点:

  • 第五步:执行完成后如果发现下一步还有await即设置了中断点,此时命令会直接跳出此方法即执行6,换句话说,await表达式执行时暂停并不构成方法退出,只会导致 finally 代码块不运行
  • 第七步:当执行当getStringTask返回结果(第七步)及await等待方法执行完成开始执行后续操作时(8)此时的线程已经和第四步执行的线程不同编号了,但是此时4所在线程上下文中的AsyncLocal变量会被复制到await返回后的线程上下文中。详细参照https://www.cnblogs.com/liyong-blackStone/p/10270526.html
  • async 和 await 关键字不会创建其他线程。 因为异步方法不会在其自身线程上运行,因此它不需要多线程.

Task简介

Task类的表示单个操作不会返回一个值,通常以异步方式执行Task对象是一种的中心思想基于任务的异步模式。首次引入.NET Framework 4 中。

Task可以通过以下几种方式开始执行:

            Task.Run(() =>
{
Console.WriteLine("无返回值委托");
});
Task.Run<int>(() =>
{
Console.WriteLine("带返回值委托");
return 1;
});
Task t = new Task(() =>
{
Console.WriteLine("声明一个Task可以后续通过t.run执行");
});
TaskFactory factory = new TaskFactory();
factory.StartNew<int>(() =>
{
Console.WriteLine("通过TaskFactory执行");
return 1;
});
Task t4 = new Task(() =>
{
Console.WriteLine("同步执行");
});
// 同步执行
t4.RunSynchronously();

task的执行方式这里不多做介绍,下面主要说下Task的异常处理。

异步方法内部的异常处理

.Net中异步方法由 async修饰符标记,通常包含一个或多个await表达式或语句。await表达式将await运算符应用于 Task 或Task。由于在异步方法中通常会存在多个线程,而子线程中的异常信息不能自动的抛到主线程上,所以要想在主线程上获得子线程的异常信息,需要借助于返回的task这个对象。以下为Msdn给出的一段示例代码:

public async Task DoSomethingAsync()
{
Task<string> theTask = DelayAsync(); try
{
string result = await theTask;
Debug.WriteLine("Result: " + result);
}
catch (Exception ex)
{
Debug.WriteLine("Exception Message: " + ex.Message);
}
Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled);
Debug.WriteLine("Task IsFaulted: " + theTask.IsFaulted);
if (theTask.Exception != null)
{
Debug.WriteLine("Task Exception Message: "
+ theTask.Exception.Message);
Debug.WriteLine("Task Inner Exception Message: "
+ theTask.Exception.InnerException.Message);
}
} private async Task<string> DelayAsync()
{
await Task.Delay(100); // Uncomment each of the following lines to
// demonstrate exception handling. //throw new OperationCanceledException("canceled");
//throw new Exception("Something happened.");
return "Done";
} // Output when no exception is thrown in the awaited method:
// Result: Done
// Task IsCanceled: False
// Task IsFaulted: False // Output when an Exception is thrown in the awaited method:
// Exception Message: Something happened.
// Task IsCanceled: False
// Task IsFaulted: True
// Task Exception Message: One or more errors occurred.
// Task Inner Exception Message: Something happened. // Output when a OperationCanceledException or TaskCanceledException
// is thrown in the awaited method:
// Exception Message: canceled
// Task IsCanceled: True
// Task IsFaulted: False

对于异步线程的执行结果,最多有三种情况

  • 正常执行结束:可以通过IsCompletedSuccessfully 属性表示任务正常结束,并成功执行。特别说明:IsCompleted为true只能表示执行完成,当任务处于三种最终状态之一: RanToCompletion, Faulted,或Canceled。时他都为true
  • 发生异常:发生异常时,可以通过返回的task对象中的IsFaulted属性判断,为true时表示发生异常,如果要获取具体的异常信息,可以通过以下以下方式获取
    task.Exception.InnerException.Message
  • 异步线程被取消:异步线程被取消时task中的IsCanceled属性会被设置为true

    了解取消任务可以参考msdn示例:
using System;
using System.Threading;
using System.Threading.Tasks; public class Example
{
public static void Main()
{
// Create a cancellation token and cancel it.
var source1 = new CancellationTokenSource();
var token1 = source1.Token;
source1.Cancel();
// Create a cancellation token for later cancellation.
var source2 = new CancellationTokenSource();
var token2 = source2.Token; // Create a series of tasks that will complete, be cancelled,
// timeout, or throw an exception.
Task[] tasks = new Task[12];
for (int i = 0; i < 12; i++)
{
switch (i % 4)
{
// Task should run to completion.
case 0:
tasks[i] = Task.Run(() => Thread.Sleep(2000));
break;
// Task should be set to canceled state.
case 1:
tasks[i] = Task.Run( () => Thread.Sleep(2000),
token1);
break;
case 2:
// Task should throw an exception.
tasks[i] = Task.Run( () => { throw new NotSupportedException(); } );
break;
case 3:
// Task should examine cancellation token.
tasks[i] = Task.Run( () => { Thread.Sleep(2000);
if (token2.IsCancellationRequested)
token2.ThrowIfCancellationRequested();
Thread.Sleep(500); }, token2);
break;
}
}
Thread.Sleep(250);
source2.Cancel(); try {
Task.WaitAll(tasks);
}
catch (AggregateException ae) {
Console.WriteLine("One or more exceptions occurred:");
foreach (var ex in ae.InnerExceptions)
Console.WriteLine(" {0}: {1}", ex.GetType().Name, ex.Message);
} Console.WriteLine("\nStatus of tasks:");
foreach (var t in tasks) {
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status);
if (t.Exception != null) {
foreach (var ex in t.Exception.InnerExceptions)
Console.WriteLine(" {0}: {1}", ex.GetType().Name,
ex.Message);
}
}
}
}
// The example displays output like the following:
// One or more exceptions occurred:
// TaskCanceledException: A task was canceled.
// NotSupportedException: Specified method is not supported.
// TaskCanceledException: A task was canceled.
// TaskCanceledException: A task was canceled.
// NotSupportedException: Specified method is not supported.
// TaskCanceledException: A task was canceled.
// TaskCanceledException: A task was canceled.
// NotSupportedException: Specified method is not supported.
// TaskCanceledException: A task was canceled.
//
// Status of tasks:
// Task #13: RanToCompletion
// Task #1: Canceled
// Task #3: Faulted
// NotSupportedException: Specified method is not supported.
// Task #8: Canceled
// Task #14: RanToCompletion
// Task #4: Canceled
// Task #6: Faulted
// NotSupportedException: Specified method is not supported.
// Task #7: Canceled
// Task #15: RanToCompletion
// Task #9: Canceled
// Task #11: Faulted
// NotSupportedException: Specified method is not supported.
// Task #12: Canceled

.Net 多线程 异步编程 Await、Async和Task的更多相关文章

  1. 多线程异步编程示例和实践-Task

    上篇博文中,我们介绍了Thread和ThreadPool: 多线程异步编程示例和实践-Thread和ThreadPool 本文中我们继续,说一下TPL(Task Parallel Library, 简 ...

  2. C#——await与async实现多线程异步编程

    曾经,我们也许用过Thread.在主线程运行的时候.新开还有一个新线程,来运行新方法. 今天看别人发给我的一段代码的时候发现了一个不认识的await,可是又感觉非常熟悉的样子,感觉是线程那块儿的东西, ...

  3. 重新想象 Windows 8 Store Apps (44) - 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换

    [源码下载] 重新想象 Windows 8 Store Apps (44) - 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换 作者:webabcd 介绍 ...

  4. .Net 4.5 异步编程初试(async和await)

    .Net 4.5 异步编程初试(async和await) 前言 最近自己在研究Asp.Net Web API.在看到通过客户端来调用Web API的时候,看到了其中的异步编程,由于自己之前没有接触过, ...

  5. 异步编程(Async和Await)的使用

    .net4.5新特性之异步编程(Async和Await)的使用 一.简介 首先来看看.net的发展中的各个阶段的特性:NET 与C# 的每个版本发布都是有一个“主题”.即:C#1.0托管代码→C#2. ...

  6. 多线程异步编程示例和实践-Thread和ThreadPool

    说到多线程异步编程,总会说起Thread.ThreadPool.Task.TPL这一系列的技术.总结整理了一版编程示例和实践,分享给大家. 先从Thread和ThreadPool说起: 1. 创建并启 ...

  7. 多线程之异步编程: 经典和最新的异步编程模型,async与await

    经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...

  8. C# 异步编程(async&await)

    同步:同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去 异步:异步是指进程不需要一直等下去,而是继续执行下面的操作 ...

  9. .NET4.5新特性之异步编程(Async和Await)的使用

    一.简介 首先来看看.net的发展中的各个阶段的特性:NET 与C# 的每个版本发布都是有一个"主题".即:C#1.0托管代码→C#2.0泛型→C#3.0LINQ→C#4.0动态语 ...

随机推荐

  1. mybatis 全局配置文件

    传送门:mybatis XML 映射配置文件官方文档 配置文件中的标签顺序不能颠倒,否则会报错. <?xml version="1.0" encoding="UTF ...

  2. 解决应用商店错误代码0x80072efd、0x80131505的方法

    解决应用商店错误代码0x80072efd.0x80131505的方法 使用win10系统的朋友应该都会经常使用应用商店这个程序吧?它是微软自带的软件下载程序!不过最近有位win10的朋友告诉小编,他的 ...

  3. android stdio Error Could not find com.android.tools common 25.2.2

    Error:Could not find com.android.tools:common:25.2.2. Searched in the following locations: file:/D:/ ...

  4. json-lib.jar开发包及依赖包的下载地址(转)

    一.去官方下载json-lib工具包下载地址:http://sourceforge.net/projects/json-lib/files/json-lib/json-lib-2.4/目前最新的是2. ...

  5. web的脚本安全-XSS

    XSS,即Cross Site Scripting,叫X是因为之前有了一个CSS.中文可以叫跨站脚本攻击.是前端工程师的一大威胁. XSS的根本,就是有恶意用户把代码植入了你要访问的页面中,从而控制你 ...

  6. js获取上一个兄弟元素

    需要用到的两个属性:previousSbiling和previousElementSibling previousSibling:获取元素的上一个兄弟节点:(既包含元素节点.文本节点.注释节点) pr ...

  7. Git 的4个阶段的撤销更改

    虽然git诞生距今已有12年之久,网上各种关于git的介绍文章数不胜数,但是依然有很多人(包括我自己在内)对于它的功能不能完全掌握.以下的介绍只是基于我个人对于git的理解,并且可能生编硬造了一些不完 ...

  8. JDK7 异常的多重捕获

    Java 7之前的版本: 1 2 3 4 5 6 7 8 9 10 catch (IOException ex) {      logger.error(ex);      throw new MyE ...

  9. git 删除远程分支文件夹

    把不需要版本控制的文件提交到远程分支上后,需要删除远程分支上的文件,用以下操作即可: git rm -r –cached dirname //删除远程文件夹,但保留本地文件夹 git commit - ...

  10. superset----缓存之redis

    一.概述 Superset使用Flask-Cache进行缓存,Flask-Cache支持redis,memcached,simplecache(内存),或本地文件系统)等缓存后端,如果你打算使用mem ...