C# 异步执行操作
为了方便测试异步,先加个计时
计时相关(可以直接跳过该部分)
//开始计时
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
// 停止计时
stopwatch.Stop();
//输出计时毫秒数
stopwatch.ElapsedMilliseconds
阻塞延迟,下面两个分别表示阻塞三秒钟
同步阻塞:Thread.Sleep(TimeSpan.FromSeconds(3))
异步阻塞:Task.Delay(3000)
Thread.Sleep(TimeSpan.FromSeconds(3)):
所属命名空间:System.Threading.Thread
使用线程阻塞:调用该方法会导致当前线程被阻塞,即挂起当前线程的执行。
同步操作:Thread.Sleep 是同步的,意味着它会阻塞当前线程并占用系统资源。
精度较低:具体的暂停时间不一定非常准确,可能会稍微长一些。
Task.Delay(3000):
所属命名空间:System.Threading.Tasks.Task
使用任务异步操作:通过异步编程模型进行操作,异步等待指定的时间。
非阻塞操作:Task.Delay 是异步的,不会阻塞当前线程,而是让线程可以执行其他任务。
高精度定时器:提供更高的精度,具有更准确的延迟时间。
可以与 async/await 一起使用:await Task.Delay 可以与其他异步操作一起使用,提供更灵活和响应式的编程体验。
优缺点比较:
Thread.Sleep 的优点是简单直接,适用于简单的线程阻塞场景。然而,它会阻塞当前线程,并且在等待的过程中,当前线程将无法执行其他任务。
Task.Delay 的优点是允许异步等待一段时间,不会阻塞当前线程,可以与其他异步操作一起使用,提供更高的性能和响应能力。
此外,它还提供了更准确的定时精度。但是,如果不需要进行异步编程,或者代码基于旧版本.NET Framework,可能不适合使用。
介绍异步几个关键字
Task(任务):Task 是.NET Framework 和 .NET Core 中的一个类型,表示一个异步操作的单元。它可以被执行、等待和取消,并且可以返回结果。可以通过 Task.Run 方法创建一个 Task。
async/await 关键字:async/await 是 C# 5.0 引入的语言特性,用于简化异步编程。在方法定义前加上 async 关键字来表示这是一个异步方法,然后可以在方法体内使用 await 关键字来暂停方法的执行,等待一个异步操作完成,然后继续执行后续的代码。被 await 修饰的表达式必须是一个返回 Task 或 Task<T> 的异步方法调用。
await 关键字:await 关键字用于异步方法内部,表示等待一个异步操作完成。当遇到 await 关键字时,方法会立即返回给调用者,同时异步操作开始执行。等待的过程中,线程可以自由地执行其他任务。当异步操作完成后,该方法会恢复执行,并返回异步操作的结果。
Task.WhenAll 方法:Task.WhenAll 方法用于等待多个异步任务完成。它接受一个 Task 数组或可迭代对象作为参数,并返回一个新的 Task,该 Task 在所有传递的任务都完成后变为完成状态。你可以使用 await Task.WhenAll 来等待多个任务同时完成。
常见的属性
Task.Status 属性:表示任务的状态,有以下几种可能的值:
- Created:任务已创建但未开始执行。
- WaitingForActivation:任务在等待激活,即还未被调度器执行。
- WaitingToRun:任务已被调度器接受,并等待在可用线程上运行。
- Running:任务正在执行。
- WaitingForChildrenToComplete:父任务正在等待其所有子任务完成。
- RanToCompletion:任务成功完成。
- Faulted:任务发生了异常。
- Canceled:任务被取消。
Task.Result 属性:获取异步操作的返回结果。该属性只能在异步操作完成后使用,并且会阻塞当前线程直到异步操作完成。
下面上代码示例
async Task Main()
{
//计时
Stopwatch stopwatch = new Stopwatch();
// 开始计时
stopwatch.Start();
//执行顺序和添加顺序有关
await Task.WhenAll(A());//先执行A
await Task.WhenAll(B());//等待A执行完再执行B
List<Task> tasks = new List<Task>()
{ C(),D() };//等待B执行完后CD一起执行
//也可以逐个添加
//tasks.Add(A());
//tasks.Add(B());
//tasks.Add(C());
//tasks.Add(D()); // 等待CD方法全部完成
await Task.WhenAll(tasks);
// 停止计时
stopwatch.Stop();
Console.WriteLine($"计时结束!总共用时:{stopwatch.ElapsedMilliseconds} 毫秒");
} async Task A()
{
Console.WriteLine("阻塞3秒");
await Task.Delay(3000);
Console.WriteLine("3秒结束");
}
async Task B()
{
Console.WriteLine("阻塞2秒");
await Task.Delay(2000);
Console.WriteLine("2秒结束");
}
async Task C()
{
Console.WriteLine("阻塞5秒");
await Task.Delay(5000);
Console.WriteLine("5秒结束");
}
async Task D()
{
Console.WriteLine("阻塞10秒");
await Task.Delay(10000);
Console.WriteLine("10秒结束");
}
C# 异步执行操作的更多相关文章
- 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)
首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...
- [源码解析] PyTorch 分布式(16) --- 使用异步执行实现批处理 RPC
[源码解析] PyTorch 分布式(16) --- 使用异步执行实现批处理 RPC 目录 [源码解析] PyTorch 分布式(16) --- 使用异步执行实现批处理 RPC 0x00 摘要 0x0 ...
- Java使用多线程异步执行批量更新操作
import com.google.common.collect.Lists; import org.apache.commons.collections.CollectionUtils; impor ...
- [.NET] 利用 async & await 进行异步 IO 操作
利用 async & await 进行异步 IO 操作 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/6082673.html 序 上次,博主 ...
- android内部培训视频_第四节(1)_异步网络操作
第四节(1):异步网络操作 一.结合asyncTask下载网络图片 1.定义下载类,继承自asyncTask,参数分别为:String(url地址),Integer(刻度,本例没有用到),BitMa ...
- Python开发程序:RPC异步执行命令(RabbitMQ双向通信)
RPC异步执行命令 需求: 利用RibbitMQ进行数据交互 可以对多台服务器进行操作 执行命令后不等待命令的执行结果,而是直接让输入下一条命令,结果出来后自动打印 实现异步操作 不懂rpc的请移步h ...
- ajax同步、异步执行简单理解与证明
此理解范例代码来自前几篇随笔! 首先我们来先了解下AJAX: Ajax:全称“Asynchronous Javascript and XML”(异步Javascript和XML),他是由Javascr ...
- node.js零基础详细教程(4):node.js事件机制、node异步IO操作
第四章 建议学习时间3小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...
- Go同步和异步执行多个任务封装
同步执行类RunnerAsync 支持返回超时检测,系统中断检测 错误常量定义 //超时错误 var ErrTimeout = errors.New("received timeout&qu ...
- 获取node异步执行结果的方式
拿数据库操作举例: var connection = mysql.createConnection(); connection.query(sql,function(err,rows){xxx} ); ...
随机推荐
- vernemq 一个可用的入门指南之一:Mac下的安装及使用,使用MQTTX访问verneMQ
因为百度到一篇简书的,不可用,所以写这么一篇,方便后来人 物联网的消息队列技术选型,很多地方会推荐使用VerneMQ,这里做一个安装实验记录,并非推荐. git clone https://githu ...
- 2023-06-03:redis中pipeline有什么好处,为什么要用 pipeline?
2023-06-03:redis中pipeline有什么好处,为什么要用 pipeline? 答案2023-06-03: Redis客户端执行一条命令通常包括以下四个阶段: 1.发送命令:客户端将要执 ...
- [MAUI程序设计] 用Handler实现自定义跨平台控件
@ 目录 Handler 与Xamarin.Forms实现的区别 为什么要用Handler代替Renderer 解耦 生命周期管理 更细粒度的控制 用Effect来实现呢? 自定义手势监听控件 在各平 ...
- 【可视化大屏】用Python开发「淄博烧烤」微博热评舆情分析大屏
目录 一.开发背景 二.爬虫代码 2.1 爬微博列表 2.2 爬微博评论 2.3 导入MySQL数据库 三.可视化代码 3.1 大标题 3.2 词云图(含:加载停用词) 3.3 玫瑰图(含:snown ...
- 安装指定版本的mysql(mysql5.7)
安装指定版本的mysql(mysql5.7) 目标:解决需求,安装mysql5.7 前言: 安装软件的三种方式: rpm 安装 源代码编译安装 yum仓库安装 本地光盘 阿里云yum源 自建yum仓库 ...
- FPGA加速技术在游戏和娱乐系统中的应用:实现高效的游戏和娱乐系统
目录 1. 引言 2. 技术原理及概念 3. 实现步骤与流程 4. 应用示例与代码实现讲解 <35. FPGA加速技术在游戏和娱乐系统中的应用:实现高效的游戏和娱乐系统>这篇文章是一篇针对 ...
- load initialize总结
load initialize 方法的区别1.调用的方式 - load 根据函数地址调用 - initialize 通过objc_msgsend调用 2.调用时刻 - load runtime 加载类 ...
- OSS的使用(谷粒商城58-64)
OSS的使用(谷粒商城58-64) 购买之类的就不在这里详述了,阿里云文档几乎都写了 创建bucket 学习阶段,相对独特的点在于我们需要选择公共读 项目开发阶段,不能选择公共读了,要尽量选择私有(代 ...
- 2023-07-22:一共有n个项目,每个项目都有两个信息, projects[i] = {a, b}, 表示i号项目做完要a天,但是当你投入b个资源,它就会缩短1天的时间, 你一共有k个资源,你的目
2023-07-22:一共有n个项目,每个项目都有两个信息, projects[i] = {a, b}, 表示i号项目做完要a天,但是当你投入b个资源,它就会缩短1天的时间, 你一共有k个资源,你的目 ...
- 通过Proxy和Reflect实现vue的响应式原理
vue3通过Proxy+Reflect实现响应式,vue2通过defineProperty来实现 Proxy Proxy是什么 Proxy是ES6中增加的类,表示代理. 如果我们想要监听对象的操作过程 ...