C#异步和多线程,Thread,Task和async/await关键字--12
目录
一.多线程和异步的区别
1.多线程
2.异步编程
多线程和异步的区别
二.Thread,Task和async/await关键字的区别
1.Thread
2.Task
3.async/await
三.Thread,Task和async/await关键字的详细对比
1.Thread和Task的详细对比
2.Task 与 async/await 的配合使用
3. async/await 的实际应用场景
4.关键区别总结
引言:在 C# 编程中,多线程和异步编程都是用于提高应用程序性能和响应性的技术,但它们的用途和实现方式有所不同
一.多线程和异步的区别
1.多线程
定义:
- 多线程是指在一个应用程序中同时运行多个线程,每个线程都独立执行代码.这些线程可能在多个处理器核心上并行运行,也可能在单个核心上通过时间片轮转方式运行
特性:
- 并行执行:多个线程可以并行执行任务,提高 CPU 利用率,适用于 CPU 密集型任务
- 共享内存空间:同一进程中的线程共享内存空间,可以方便地共享数据,但也需要处理同步问题
- 线程管理:需要开发者手动管理线程的创建,启动,同步和销毁
使用场景:
- 需要并行处理多个 CPU 密集型任务,以充分利用多核 CPU 的能力
- 需要在后台执行复杂计算,同时保持应用程序的响应性
2.异步编程
定义:
- 异步编程是一种编程范式,允许程序在等待长时间运行的操作(如 I/O、网络请求)完成时,不阻塞当前线程,从而提高应用程序的响应性和效率
特性:
- 非阻塞:异步操作不会阻塞线程,当前线程可以继续执行其他任务
- 事件驱动:通过回调,事件或任务的方式在操作完成时通知应用程序
- 适用于 I/O 密集型任务:特别是磁盘,网络等 I/O 操作,这些操作等待时间长,CPU 利用率低
使用场景:
- 防止界面卡顿:在 GUI 应用程序中,防止长时间的操作阻塞 UI 线程,保持界面响应性
- 服务器高并发:在服务器应用中,异步操作可以处理大量并发 I/O 请求,提高吞吐量
多线程和异步的区别
// 多线程示例
public void ThreadMethod()
{// 创建新线程Thread thread = new Thread(() =>{// 这段代码在新线程上运行DoSomeWork();});thread.Start();
}// 异步示例
public async Task AsyncMethod()
{// 不会创建新线程,而是在当前线程上异步执行await Task.Run(() =>{DoSomeWork();});
}
- 目的不同:多线程主要用于并行执行 CPU 密集型任务,异步编程主要用于非阻塞地执行 I/O 密集型任务
- 实现方式:多线程通过创建和管理线程实现并行,异步编程通过非阻塞的操作和回调机制实现,不一定需要多线程
- 资源利用:多线程可能会创建大量线程,占用系统资源;异步编程通常使用回调或任务,不需要额外的线程
// 多线程示例 - CPU密集型计算 public void ThreadExample() {Thread calculateThread = new Thread(() =>{// 复杂计算for (int i = 0; i < 1000000; i++){// 进行大量计算}});calculateThread.Start(); }// 异步示例 - I/O操作 public async Task AsyncExample() {// 读取文件string content = await File.ReadAllTextAsync("file.txt");// 发送网络请求var response = await httpClient.GetAsync("http://api.example.com"); }
二.Thread,Task和async/await关键字的区别
1.Thread
定义:
System.Threading.Thread类表示 .NET 中的一个线程,可以用来手动创建,控制和管理线程
特性:
- 直接映射到操作系统线程:每个
Thread实例对应一个操作系统线程 - 手动管理:需要手动创建,启动和销毁线程,以及处理线程同步问题
- 开销较大:创建和销毁线程的开销较大,过多的线程可能导致系统性能下降
使用场景:
- 需要对线程有精细的控制,比如设置线程优先级,堆栈大小,文化信息等
- 特定场景下需要手动管理线程的生命周期
示例代码:
// 创建第一个线程Thread thread1 = new Thread(() =>{for (int i = 0; i < 5; i++){Console.WriteLine($"线程1正在执行: {i}");Thread.Sleep(2000); // 暂停2秒}});// 创建第二个线程Thread thread2 = new Thread(new ThreadStart(Thread2Method));// 启动线程Console.WriteLine("开始执行线程...");thread1.Start();thread2.Start();// 等待线程结束//Join方法用于等待线程结束,即等待线程中的代码执行完毕。thread1.Join();thread2.Join();Console.WriteLine("所有线程执行完毕!");Console.ReadKey();
}// 第二个线程要执行的方法
static void Thread2Method()
{for (int i = 0; i < 5; i++){Console.WriteLine($"线程2正在执行: {i}");Thread.Sleep(800); // 暂停0.8秒}
}
2.Task
定义:
System.Threading.Tasks.Task类代表一个异步操作,可以理解为更高级别的异步编程抽象
特性:
- 基于任务的异步模式(TAP):使用任务来表示异步操作,可以更方便地组合,链接和处理任务
- 线程池:
Task默认会使用线程池中的线程,而不是创建新的线程,从而减少开销 - 支持结果值:
Task<TResult>可以返回计算结果 - 与
async/await协同工作:Task可以与async/await关键字配合使用,简化异步编程
使用场景:
- 执行异步操作,无需手动管理线程。
- 需要组合多个异步操作,或处理异步操作的结果。
static async Task Main(string[] args){Console.WriteLine("开始任务示例...");// 1. 基本的异步任务await SimpleTaskAsync();// 2. 带返回值的任务int result = await CalculateAsync();Console.WriteLine($"计算结果: {result}");// 3. 并行任务await ParallelTasksAsync();// 4. 任务超时处理await TaskWithTimeoutAsync();Console.WriteLine("所有任务完成!");Console.ReadKey();}// 基本异步任务static async Task SimpleTaskAsync(){Console.WriteLine("开始简单任务");await Task.Delay(1000); // 模拟耗时操作Console.WriteLine("简单任务完成");}// 带返回值的异步任务static async Task<int> CalculateAsync(){Console.WriteLine("开始计算");await Task.Delay(2000); // 模拟复杂计算return 42;}// 并行任务示例static async Task ParallelTasksAsync(){Console.WriteLine("开始并行任务");var task1 = Task.Run(async () =>{await Task.Delay(1000);Console.WriteLine("任务1完成");});var task2 = Task.Run(async () =>{await Task.Delay(2000);Console.WriteLine("任务2完成");});// 等待所有任务完成await Task.WhenAll(task1, task2);Console.WriteLine("所有并行任务完成");}// 带超时的任务static async Task TaskWithTimeoutAsync(){Console.WriteLine("开始超时任务");try{using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));await Task.Delay(3000, cts.Token); // 这个任务会超时Console.WriteLine("此行不会执行");}catch (TaskCanceledException){Console.WriteLine("任务已超时");}}
3.async/await
定义:async/await是 C# 中用于简化异步编程的关键字
特性:
async方法:使用async修饰的方法表示其内部可能包含异步操作,可以使用await关键字await关键字:用于等待一个异步任务完成,而不会阻塞当前线程- 编译器支持:编译器会将
async方法转换为状态机,处理异步操作的调度
使用场景:
- 希望以同步的方式编写异步代码,提高代码的可读性和维护性。
- 在 GUI 或服务器应用中,防止长时间的操作阻塞线程。
三.Thread,Task和async/await关键字的详细对比
1.Thread和Task的详细对比
// Thread 示例
Thread thread = new Thread(() =>
{Console.WriteLine("使用 Thread 执行工作");Thread.Sleep(1000);
});
thread.Start();// Task 示例
Task task = Task.Run(() =>
{Console.WriteLine("使用 Task 执行工作");Thread.Sleep(1000);
});
主要区别:
Thread:
- 直接映射到操作系统线程
- 资源开销大
- 无法直接返回结果
- 不易于管理和组合
Task:
- 使用线程池
- 可以返回结果
- 支持取消、延续、异常处理
- 易于组合和管理
2.Task 与 async/await 的配合使用
// Task 单独使用
public Task<int> GetDataAsync()
{return Task.Run(() => {// 执行一些耗时操作Thread.Sleep(1000);return 42;});
}// 使用 async/await
public async Task<int> GetDataAsyncWithAwait()
{Console.WriteLine("开始");await Task.Delay(1000); // 异步等待Console.WriteLine("结束");return 42;
}
3. async/await 的实际应用场景
// 文件操作示例
public async Task SaveFileAsync(string content)
{Console.WriteLine("开始保存文件");await File.WriteAllTextAsync("test.txt", content);Console.WriteLine("文件保存完成");
}// 多个异步操作组合
public async Task ProcessDataAsync()
{try{// 并行执行多个异步操作var task1 = Task.Delay(1000);var task2 = Task.Delay(2000);await Task.WhenAll(task1, task2);// 串行执行异步操作var result1 = await GetDataAsync();var result2 = await ProcessResultAsync(result1);}catch (Exception ex){Console.WriteLine($"错误: {ex.Message}");}
}
4.关键区别总结
1)执行模型:
- Thread: 一个线程执行一个任务
- Task: 可以使用线程池,更灵活
- async/await: 不创建新线程,而是管理异步操作
2)资源使用:
- Thread: 每个线程占用约1MB内存
- Task: 更轻量级,共享线程池
- async/await: 几乎没有额外开销
3)使用场景:
- Thread: 需要直接控制线程时
- Task: 执行后台操作,需要返回结果时
- async/await: IO操作,网络请求等不需要CPU计算的操作
4)代码可维护性:
- Thread: 较难管理和维护
- Task: 提供更好的控制和组合
- async/await: 提供最清晰的代码结构
在实际的开发中优先使用 async/await 处理异步操作,需要并行计算时使用 Task,只在特殊情况下使用 Thread
相关文章:
C#异步和多线程,Thread,Task和async/await关键字--12
目录 一.多线程和异步的区别 1.多线程 2.异步编程 多线程和异步的区别 二.Thread,Task和async/await关键字的区别 1.Thread 2.Task 3.async/await 三.Thread,Task和async/await关键字的详细对比 1.Thread和Task的详细对比 2.Task 与 async/await 的配合使用 3. asy…...
使用分割 Mask 和 K-means 聚类获取天空的颜色
引言 在计算机视觉领域,获取天空的颜色是一个常见任务,广泛应用于天气分析、环境感知和图像增强等场景。本篇博客将介绍如何通过已知的天空区域 Mask 提取天空像素,并使用 K-means 聚类分析天空颜色,最终根据颜色占比查表得到主导…...
145.《redis原生超详细使用》
文章目录 什么是redisredis 安装启动redis数据类型redis key操作key 的增key 的查key 的改key 的删key 是否存在key 查看所有key 「设置」过期时间key 「查看」过期时间key 「移除」过期时间key 「查看」数据类型key 「匹配」符合条件的keykey 「移动」到其他数据库 redis数据类…...
Pytorch基础教程:从零实现手写数字分类
文章目录 1.Pytorch简介2.理解tensor2.1 一维矩阵2.2 二维矩阵2.3 三维矩阵 3.创建tensor3.1 你可以直接从一个Python列表或NumPy数组创建一个tensor:3.2 创建特定形状的tensor3.3 创建三维tensor3.4 使用随机数填充tensor3.5 指定tensor的数据类型 4.tensor基本运算…...
【SH】Xiaomi9刷Windows10系统研发记录 、手机刷Windows系统教程、小米9重装win10系统
文章目录 参考资料云盘资料软硬件环境手机解锁刷机驱动绑定账号和设备解锁手机 Mindows工具箱安装工具箱和修复下载下载安卓和woa资源包第三方Recovery 一键安装Windows准备工作创建分区安装系统 效果展示Windows和Android一键互换Win切换安卓安卓切换Win 删除分区 参考资料 解…...
excel仅复制可见单元格,仅复制筛选后内容
背景 我们经常需要将内容分给不同的人,做完后需要合并 遇到情况如下 那是因为直接选择了整列,当然不可以了。 下面提供几种方法,应该都可以 直接选中要复制区域然后复制,不要选中最上面的列alt;选中可见单元格正常复制ÿ…...
HBASE学习(一)
1.HBASE基础架构, 1.1 参考: HBase集群架构与读写优化:理解核心机制与性能提升-CSDN博客 1.2问题: 1.FLUSH对hbase的影响 2. HLog和memstore的区别 hlog中存储的是操作记录,比如写、删除。而memstor中存储的是写入…...
element select 绑定一个对象{}
背景: select组件的使用,适用广泛的基础单选 v-model 的值为当前被选中的 el-option 的 value 属性值。但是我们这里想绑定一个对象,一个el-option对应的对象。 <el-select v-model"state.form.modelA" …...
Sprint Boot教程之五十八:动态启动/停止 Kafka 监听器
Spring Boot – 动态启动/停止 Kafka 监听器 当 Spring Boot 应用程序启动时,Kafka Listener 的默认行为是开始监听某个主题。但是,有些情况下我们不想在应用程序启动后立即启动它。 要动态启动或停止 Kafka Listener,我们需要三种主要方法…...
C:JSON-C简介
介绍 JSON-C是一个用于处理JSON格式数据的C语言库,提供了一系列操作JSON数据的函数。 一、json参数类型 typedef enum json_type { json_type_null, json_type_boolean, json_type_double, json_type_int, json_type_object, json_type_ar…...
业务幂等性技术架构体系之消息幂等深入剖析
在系统中当使用消息队列时,无论做哪种技术选型,有很多问题是无论如何也不能忽视的,如:消息必达、消息幂等等。本文以典型的RabbitMQ为例,讲解如何保证消息幂等的可实施解决方案,其他MQ选型均可参考。 一、…...
【Go】Go Gin框架初识(一)
1. 什么是Gin框架 Gin框架:是一个由 Golang 语言开发的 web 框架,能够极大提高开发 web 应用的效率! 1.1 什么是web框架 web框架体系图(前后端不分离)如下图所示: 从上图中我们可以发现一个Web框架最重要…...
2024年合肥市科普日小学组市赛第一题题解
9304:数字加密(encrypt)(1) 【问题描述】 在信息科技课堂上,小肥正在思考“数字加密”实验项目。项目需要加密n个正整数,对每一个正整数x加密的规则是,将x的每一位数字都替换为x的最大数字。例如࿰…...
【MySQL实战】mysql_exporter+Prometheus+Grafana
要在Prometheus和Grafana中监控MySQL数据库,如下图: 可以使用mysql_exporter。 以下是一些步骤来设置和配置这个监控环境: 1. 安装和配置Prometheus: - 下载和安装Prometheus。 - 在prometheus.yml中配置MySQL通过添加以下内…...
Wireshark 使用教程:网络分析从入门到精通
一、引言 在网络技术的广阔领域中,网络协议分析是一项至关重要的技能。Wireshark 作为一款开源且功能强大的网络协议分析工具,被广泛应用于网络故障排查、网络安全检测以及网络协议研究等诸多方面。本文将深入且详细地介绍 Wireshark 的使用方法&#x…...
如何在前端给视频进行去除绿幕并替换背景?-----Vue3!!
最近在做这个这项目奇店桶装水小程序V1.3.9安装包骑手端V2.0.1小程序前端 最近,我在进行前端开发时,遇到了一个难题“如何给前端的视频进行去除绿幕并替换背景”。这是一个“数字人项目”所需,我一直在冥思苦想。终于有了一个解决方法…...
使用中间件自动化部署java应用
为了实现你在 IntelliJ IDEA 中打包项目并通过工具推送到两个 Docker 服务器(172.168.0.1 和 172.168.0.12),并在推送后自动或手动重启容器,我们可以按照以下步骤进行操作: 在 IntelliJ IDEA 中配置 Maven 或 Gradle 打…...
pytorch张量分块投影示例代码
张量的投影操作 背景 张量投影 是深度学习中常见的操作,将输入张量通过线性变换映射到另一个空间。例如: Y=W⋅X+b 其中: X: 输入张量(形状可能为 (B,M,K),即批量维度、序列维度、特征维度)。W: 权重矩阵((K,N),将 K 维投影到 N 维)。b: 偏置向量(可选,(N,))。Y:…...
Visual Studio 同一解决方案 同时运行 多个项目
方案一 方案二...
VMware中Ubuntu如何连接网络?安排!
一、设置NAT模式 1、关闭Ubuntu虚拟机: 确保Ubuntu已经完全关机,而不是挂起或休眠状态。 2、编辑虚拟网络设置: 在VMware主界面点击“编辑”菜单,选择“虚拟网络编辑器”。 如果需要,选择VMnet8 (NAT模式)并点击“更改…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...
qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...
用js实现常见排序算法
以下是几种常见排序算法的 JS实现,包括选择排序、冒泡排序、插入排序、快速排序和归并排序,以及每种算法的特点和复杂度分析 1. 选择排序(Selection Sort) 核心思想:每次从未排序部分选择最小元素,与未排…...
react-pdf(pdfjs-dist)如何兼容老浏览器(chrome 49)
之前都是使用react-pdf来渲染pdf文件,这次有个需求是要兼容xp环境,xp上chrome最高支持到49,虽然说iframe或者embed都可以实现预览pdf,但为了后续的定制化需求,还是需要使用js库来渲染。 chrome 49测试环境 能用的测试…...
DL00871-基于深度学习YOLOv11的盲人障碍物目标检测含完整数据集
基于深度学习YOLOv11的盲人障碍物目标检测:开启盲人出行新纪元 在全球范围内,盲人及视觉障碍者的出行问题一直是社会关注的重点。尽管技术不断进步,许多城市的无障碍设施依然未能满足盲人出行的实际需求。尤其是在复杂的城市环境中ÿ…...
World-writable config file /etc/mysql/mysql.conf.d/my.cnf is ignored
https://stackoverflow.com/questions/53741107/mysql-in-docker-on-ubuntu-warning-world-writable-config-file-is-ignored 修改权限 -> 重启mysql # 检查字符集配置 SHOW VARIABLES WHERE Variable_name IN (character_set_server, character_set_database ); --------…...
HarmonyOS-ArkUI 自定义弹窗
自定义弹窗 自定义弹窗是界面开发中最为常用的一种弹窗写法。在自定义弹窗中, 布局样式完全由您决定,非常灵活。通常会被封装成工具类,以使得APP中所有弹窗具备相同的设计风格。 自定义弹窗具备的能力有 打开弹窗自定义布局,以…...
