这节讲一下比较高级的异步编程用法Task,以及两个异步关键字async和await。

Task是在C#5.0推出的语法,它是基于任务的异步编程语法,是对Thread的升级,也提供了很多API,先看一下Task怎么使用:

System.Threading.Tasks.Task.Run(() =>
{
Console.WriteLine("异步");
});
System.Threading.Tasks.Task aTask=new System.Threading.Tasks.Task(() =>
{
Console.WriteLine("异步");
});
aTask.Start();
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
Console.WriteLine("异步");
});

Task.Run()可以直接异步运行一个方法,或者使用实例化Task传入委托的方式,通过start()进行启动,再或者使用Task.Factory.StartNew()直接启动。

async,await

为了进一步介绍Task,需要先介绍两个异步有关的关键字async,await

async用在方法的声明,await用于代码语句中。被async标记的方法,称作异步方法。但是,并非整个方法都是异步执行,代码中以await开头标记的代码,才是要真正异步执行的具体内容。这个关键字一般是配合Task来使用的,Task有泛型的形式,标识异步的返回值类型,通过Result()方法获取返回值。这段说明很难理解,下面看代码演示:

static void Main(string[] args)
{
Console.WriteLine("新建一个异步任务");
Task<int> task = new Program().GetValue();

Console.WriteLine("正在计算结果....");
Console.WriteLine($"运行结果为:{task.Result}");
Console.WriteLine("任务完成....");
}
public async Task<int> GetValue()
{
Console.WriteLine("即将开始进行计算...3");
Console.WriteLine("即将开始进行计算...2");
Console.WriteLine("即将开始进行计算...1");
int a= await System.Threading.Tasks.Task.Run(() =>
{
int i = 0;
for (; i < 10; i++)
{
Console.WriteLine(i);
}
return i;
});
Console.WriteLine("结果计算完成....");
return a;
}

运行结果为:

从运行结果可以看出,程序运行到15行await处后,下一步就跳出了这个方法,回到第6行执行,这也是await的一个特性,异步执行,将主线程执行权交回,也就是说,从15行到25行是在后台线程中执行的,之前的执行都是同步的,之后的执行也是同步的,而且,主线程的脚步没有停下,直到遇到task.Result,Result里边存放着异步方法运行的返回值,运行到这,如果异步没有完成,就会阻塞当前线程,直到异步返回结果。

另外说一点,之前在讲自定义中间件的时候,涉及到过这两个关键词,现在明白了这个用法,可以回去再看一下,应该会对中间件的访问流程有一个更清晰的理解。

ContinueWith

    ContinueWith设置Task在执行完原有任务后,再继续执行此方法设置的方法,下面看代码:

task.ContinueWith((task) =>
{
Console.WriteLine("---------------"+a.Result);
});

 这是其中的一个重载,接受一个Action<Task<T>>类型的委托,此处乍一看可能会不解,其实就是把当前执行任务的Task对象传进来了。这样的用法有什么好处呢,运行完了以后,可以直接取Task任务的返回值,不用阻塞线程,当然这是在返回值不是急需的情况下。

CancellationTokenSource

    CancellationTokenSource类用于终止一个任务,请先看一下代码:

static void Main(string[] args)
{
CancellationTokenSource cancellationToken=new CancellationTokenSource();

Task<int> task= new Program().GetValue(cancellationToken);
cancellationToken.Cancel();
Console.WriteLine("正在计算结果....");

Console.WriteLine($"运行结果为:{task.Result}");
Thread.Sleep(1000);
Console.WriteLine("任务完成....");
}
public Task<int> GetValue(CancellationTokenSource cancellationToken)
{
Task<int> a = System.Threading.Tasks.Task.Run(() =>
{
int i = 0;
for (; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(500);
}
return i;
},cancellationToken.Token);
Console.WriteLine("结果计算完成....");
return a;
}

创建一个CancellationTokenSource对象,在Run任务的时候传入一个Token,就能调用Cancel()方法就能终止这个任务,运行结果为:

可以看到报错了,这很正常,因为任务停止了,显然Result是没有值的

最后注意一点,异步不是多线程,可以说异步是基于多线程,但是它们不是等于的关系。

这是我的公众号二维码,获取最新文章,请关注此号

基于任务的异步编程(Task,async,await)的更多相关文章

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

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

  2. 异步编程(async&await)

    前言 本来这篇文章上个月就该发布了,但是因为忙 QuarkDoc 一直没有时间整理,所以耽搁到今天,现在回归正轨. C# 5.0 虽然只引入了2个新关键词:async和await.然而它大大简化了异步 ...

  3. 学习迭代器实现C#异步编程——仿async/await(一)

    .NET 4.5的async/await真是个神奇的东西,巧妙异常以致我不禁对其实现充满好奇,但一直难以窥探其门径.不意间读了此篇强文<Asynchronous Programming in C ...

  4. python3.6以上 asyncio模块的异步编程模型 async await语法

    这是python3.6以上版本的用法,本例是python3.7.2编写使用asyncio模块的异步编程模型,生产这消费者,异步生产,用sleep来代替IO等待使用async和await语法来进行描述a ...

  5. c# 异步编程demo (async await)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  6. ASP.NET 异步编程之Async await

    本文重点介绍的是.NET Framework4.5 推出的异步编程方案  async await 请先看个5分钟的微软演示的视频:视频地址: https://channel9.msdn.com/Blo ...

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

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

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

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

  9. 基于任务的异步编程模式,Task-based Asynchronous Pattern

    术语: APM           异步编程模型,Asynchronous Programming Model,其中异步操作由一对 Begin/End 方法(如 FileStream.BeginRea ...

随机推荐

  1. python torndb模块

    一.torndb概述 torndb是一个轻量级的基于MySQLdb封装的一个模块,其是tornado框架的一部分.其项目主页为:https://github.com/bdarnell/torndb . ...

  2. python flake8 代码扫描

    一.介绍 Flake8 是由Python官方发布的一款辅助检测Python代码是否规范的工具,flake8是下面三个工具的封装: PyFlakes Pep8 NedBatchelder's McCab ...

  3. The 2018 ACM-ICPC CCPC NING XIA G-Factories

    题意:在一棵数的叶子上建k个工厂保证,求两两距离之和的最小值. 思路:如果一个一个叶子节点去考虑去与否太麻烦了,直接考虑该节点的子树上选取几个作为工厂,利用树形DP,dp[u][i]表示的是u节点为根 ...

  4. 在ASP.NET Core中用HttpClient(五)——通过CancellationToken取消HTTP请求

    ​用户向服务器发送HTTP请求应用程序页面是一种非常可能的情况.当我们的应用程序处理请求时,用户可以从该页面离开.在这种情况下,我们希望取消HTTP请求,因为响应对该用户不再重要.当然,这只是实际应用 ...

  5. 【数据库】Redis(2)--Redis的常用数据类型及命令

    1.Redis主要数据类型分类 Redis中存储数据常用的数据类型主要有五种:String.List.Set.Sorted Set.Hash,这五种数据结构在Redis中存储数据的命令掌握对于我们后期 ...

  6. shell字符串处理总结

    1. 字符串切片 1.1 基于偏移量取字符串 返回字符串 string 的长度 ${#string} 示例 [root@centos8 script]#str=" I Love Python ...

  7. 带你全面认识CMMI V2.0(三)——实践域

    实践域以往被称为称为"过程域",如:配置管理,现在叫做"实践域".对于2.0版,则有25个适用的实践域.与以前版本的CMMI模型一样,"实践域&quo ...

  8. [Azure DevOps] 如何安装并配置 Build Agent

    1. 编译服务器 在 Azure Pipelines 中至少需要一个编译服务器的 Agent 才能编译代码或发布软件.Azure DevOps 本身已经提供了一个 Agent,但出于各种理由(需要特殊 ...

  9. 消息中间件-RabbitMQ持久化机制、内存磁盘控制

    RabbitMQ持久化机制 RabbitMQ内存控制 RabbitMQ磁盘控制 RabbitMQ持久化机制 重启之后没有持久化的消息会丢失 package com.study.rabbitmq.a13 ...

  10. Horovod Install

    Horovod documentation 安装 [Step1]安装Open MPI 注意: Open MPI 3.1.3 安装有些问题, 可以安装 Open MPI 3.1.2 或者 Open MP ...