.NET8.0多线程编码结合异步编码示例
1、创建一个.NET8.0控制台项目来演示多线程的应用

2、快速创建一个线程

3、多次运行程序,可以得到输出结果


这就是多线程的特点 - 当多个线程并行执行时,它们的具体执行顺序是不确定的,除非我们使用同步机制(如 lock、信号量等)来控制执行顺序。
4、新建一个类TestThread,以及一个静态的测试方法,用来做测试使用

5、在Program中,把输出改成调用TestThread类中的测试方法再次执行测试一下

6、执行以后的输出结果,如下图所示

7、Thread.Sleep(毫秒):线程的等待(睡眠)


执行结果:

8、Thread.Join() 代表线程执行完毕以后,才可以继续执行后续的代码

如下图所示,在thread线程内部执行完成以后,很快就接着执行最后的打印输出方法了

9、Thread.Join(毫秒) 代表等待当前线程执行多长时间,如果超出设定的毫秒数,就会直接执行后续的代码


运行程序,查看执行结果

1、新增Test2方法,用来测试线程池ThreadPool使用

2、WaitCallback也是一个委托,传入需要在线程池内执行的方法名称。以下代码内,“线程池”字符串为要执行方法对应的参数

ThreadPool:
这是.NET中的线程池类
它维护着一组可重用的线程
比直接创建新线程更有效率QueueUserWorkItem:
这个方法用于将工作项添加到线程池队列中
线程池会自动分配空闲线程来执行这些工作项WaitCallback:
这是一个委托类型
定义了线程池中的线程要执行的方法
可以接收一个 object 类型的参数TestThread.Test2:
这是你定义的要在线程池中执行的方法
它有这样的签名:public static void Test2(object state)"线程池":
这是传递给 Test2 方法的参数
3、除了直接传入回调方法,也可以直接在线程池开启的方法内,直接写代码块来当做多线程执行的部分


4、线程池内,可以通过设置Manual信号量,来识别线程池内的线程什么时候执行完成。


**1、创建一个TestAsyncAction类,添加一个模拟的异步方法TestAction

2、使用Task快读创建一个线程。最简单的方法:Task.Run(()=>{ 代码块 })

3、两个线程并行执行,查询执行结果

4、如果想等待新开线程执行完再继续执行后续的代码,可以使用如下方式:使用 await 等待整个操作完成
await Task.Run(async () =>
{await TestAsyncAction.TestAction();
});代码会等待异步操作完成才继续执行
执行结果:

5、也可以使用Task.Factory创建一个任务工厂来实现

6、查看执行结果

1、【异步结合多线程】如果有多个任务在执行期间,在任意一个线程执行完毕以后进行执行某种操作,可以使用 ContinueWhenAny来进行
// See https://aka.ms/new-console-template for more information
using MultiThreading;Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}>>>>Hello, World!");var tasks = new Task[3];TaskFactory factory = new();/** .Unwrap() 主要是用来处理嵌套任务问题。* 使用 StartNew 执行 async lambda 时,会得到一个 Task<Task> (双层嵌套的Task)* // 不使用 Unwrapvar task1 = factory.StartNew(async () => {await Task.Delay(1000);return "Hello";});// task1 的类型是 Task<Task<string>>// 需要两次 awaitstring result1 = await (await task1);---------------------------------------------------// 使用 Unwrapvar task2 = factory.StartNew(async () => {await Task.Delay(1000);return "Hello";}).Unwrap();// task2 的类型是 Task<string>// 只需要一次 awaitstring result2 = await task2;*/
tasks[0] = factory.StartNew(async () =>
{await TestAsyncAction.AsyncAction1();
}).Unwrap();tasks[1] = factory.StartNew(async () =>
{await TestAsyncAction.AsyncAction2();
}).Unwrap();tasks[2] = factory.StartNew(async () =>
{await TestAsyncAction.AsyncAction3();
}).Unwrap();_ = factory.ContinueWhenAny(tasks, x =>
{Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}>>>>正常代码");
});Console.ReadLine();//阻止程序退出PS:如果后续代码依赖于续联任务的完成,使用 await如果不关心续联任务何时完成,使用 _=
查看执行结果:

2、【异步结合多线程】如果要等任务全部执行完毕以后才执行某个代码块,可以使用ContinueWhenAll

查看执行结果:

PS:
// 可以使用 Task.WhenAny 替代 ContinueWhenAny
_ = Task.WhenAny(tasks).ContinueWith(t => {Console.WriteLine(">>>>正常代码");
});
3、异步方法中 使用 WhenAll 和 WhenAny(这个仅模拟纯IO操作,不涉及多线程)
当遇到 await 时,当前方法会返回到调用者主线程可以继续处理其他工作(比如UI响应、处理其他事件等)这些任务会被放到线程池中执行当前方法内 await 后面的代码会被打包成续接(continuation)这个续接会等待所有任务完成后才执行但这个等待是异步的,不会占用主线程资源
-
.WhenAll()

查看执行结果:

-
.WhenAny()

查看执行结果:

文章转载自:sq1201
原文链接:.NET8.0多线程编码结合异步编码示例 - sq1201 - 博客园
体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构
相关文章:
.NET8.0多线程编码结合异步编码示例
1、创建一个.NET8.0控制台项目来演示多线程的应用 2、快速创建一个线程 3、多次运行程序,可以得到输出结果 这就是多线程的特点 - 当多个线程并行执行时,它们的具体执行顺序是不确定的,除非我们使用同步机制(如 lock、信号量等&am…...
SpringBoot项目中解决CORS跨域资源共享问题
在Spring Boot项目中解决CORS(跨域资源共享)问题,可以通过以下几种方法: 1. 使用CrossOrigin注解 这是最简单的方法,适用于单个控制器或控制器方法级别的跨域配置。你可以在控制器类或具体的方法上使用CrossOrigin注…...
Android string.xml中特殊字符转义
项目中要在string.xml 中显示特殊符号 空格: (普通的英文半角空格但不换行) 窄空格: (中文全角空格 (一个中文宽度)) (半个中文宽度,但两个空格比一个中文…...
解析传统Workflow、AI Workflow与AI Agent概念,并通过Coze案例探讨利用AI工作流构建应用的实践流程
传统工作流 工作流入门这篇就够了 BPMN.JS中文教程 BPMN 工作流引擎解析 定义:工作流是在计算机支持下业务流程的自动或半自动化,其通过对流程进行描述以及按一定规则执行以完成相应工作。 应用:随着计算机技术的发展以及工业生产、办公自动…...
光谱相机的光谱分辨率可以达到多少?
多光谱相机 多光谱相机的光谱分辨率相对较低,波段数一般在 10 到 20 个左右,光谱分辨率通常在几十纳米到几百纳米之间,如常见的多光谱相机光谱分辨率为 100nm 左右。 高光谱相机 一般的高光谱相机光谱分辨率可达 2.5nm 到 10nm 左右&#x…...
android Recyclerview viewholder统一封装
Recyclerview holder 统一封装 ViewHolder类 import android.annotation.SuppressLint import android.content.Context import android.graphics.Color import android.graphics.drawable.GradientDrawable import android.os.Build import android.os.CountDownTimer import…...
Windows部署NVM并下载多版本Node.js的方法(含删除原有Node的方法)
本文介绍在Windows电脑中,下载、部署NVM(node.js version management)环境,并基于其安装不同版本的Node.js的方法。 在之前的文章Windows系统下载、部署Node.js与npm环境的方法(https://blog.csdn.net/zhebushibiaoshi…...
51单片机入门基础
目录 一、基础知识储备 (一)了解51单片机的基本概念 (二)掌握数字电路基础 (三)学习C语言编程基础 二、开发环境搭建 (一)硬件准备 (二)软件准备 三、…...
老centos7 升级docker.io为docker-ce 脚本
旧的centos7 之前安装的是docker.io 由于一些原因,像docker compose 等版本变化,以及docker.io源受限等,我们要更新到docker-ce 并使用国内阿里云的源怎么处理?下面直接上脚本,upgrade-docker.sh #!/bin/bashset -e# 创建临时目录 TEMP_DIR"./tmp" mkdir -p "…...
数仓建模(三)建模三步走:需求分析、模型设计与数据加载
本文包含: 数据仓库的背景与重要性数据仓库建模的核心目标本文结构概览:需求分析、模型设计与数据加载 目录 第一部分:需求分析 1.1 需求分析的定义与目标 1.2 需求分析的步骤 1.2.1 业务需求收集 1.2.2 技术需求分析 1.2.3 成果输出…...
PHP xml 常用函数整理
————————-DOM 函数————————————– 1、DOMDocument->load() 作用:加载xml文件 用法:DOMDocument->load( string filename ) 参数:filename,xml文件; 返回:如果成功则返回 TRUE&a…...
数据结构(Java版)第八期:LinkedList与链表(三)
专栏:数据结构(Java版) 个人主页:手握风云 目录 一、链表中的经典面试题 1.1. 链表分割 1.2. 链表的回文结构 1.3. 相交链表 1.4. 环形链表 一、链表中的经典面试题 1.1. 链表分割 题目中要求不能改变原来的数据顺序,也就是如上图所示。…...
数据结构学习记录-数据结构概念
1 数据结构: 数据结构是计算机存储,管理数据的方式。 数据必须依据某种逻辑联系组织在一起存储在计算机内 数据结构研究的就是这种数据的存储结构和数据的逻辑结构。 1.1 数据的逻辑结构: 逻辑结构指的是数据本身之间的关系 集合&#x…...
【Linux】11.Linux基础开发工具使用(4)
文章目录 3. Linux调试器-gdb使用3.1 背景3.2 下载安装3.3 使用gdb查询3.4 开始使用 3. Linux调试器-gdb使用 3.1 背景 程序的发布方式有两种,debug模式和release模式 Linux gcc/g出来的二进制程序,默认是release模式 要使用gdb调试,必须…...
数据结构与算法之栈: LeetCode 1047. 删除字符串中的所有相邻重复项 (Ts版)
删除字符串中的所有相邻重复项 https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/ 描述 给出由小写字母组成的字符串 s,重复项删除操作会选择两个相邻且相同的字母,并删除它们在 s 上反复执行重复项删除操作,直到无…...
C++ 在线编译软件介绍、杭电OJ、北大OJ、力扣OJ
在线编译软件的话,可见下: https://www.jyshare.com/compile/12/ 杭州电子科技大学开发的一个免费的写代码地址 ,杭电OJ https://bestcoder.hdu.edu.cn/ 北大OJ http://poj.org/ 力扣OJ 力扣 (LeetCode) 全球极客挚爱的技术成长平台...
Java学习笔记(二十三)
1 CacheEvict CacheEvict是Spring框架中用于清空缓存的注解。以下是对CacheEvict注解的详细介绍: 1.1 作用 CacheEvict注解的主要作用是删除缓存中的数据。在方法执行后或执行前(根据配置),它可以清空指定的缓存项或整个缓存区…...
《AI赋能鸿蒙Next,开启智能关卡设计新时代》
在游戏开发领域,关卡设计是至关重要的一环,它直接影响着玩家的游戏体验和沉浸感。而随着人工智能技术的飞速发展,结合鸿蒙Next系统的强大功能,为游戏的智能关卡设计带来了全新的思路和方法。 利用AI学习玩家行为模式 在鸿蒙Next…...
js:正则表达式
目录 正则表达式的语法 定义 检测 检索 元字符 边界符 量词 字符类 表单判断案例 修饰符 过滤敏感词 正则表达式是一种用于匹配和操作文本的强大工具,它是由一系列字符和特殊字符组成的模式,用于描述要匹配的文本字符组合模式 正则表达式是一…...
linux环境使用docker部署多个war项目
如果你的需求是在一个服务器上部署多个Tomcat项目,并且每个项目需要独立运行,可以通过以下方式实现: 1. 使用不同的端口 每个Tomcat项目可以使用不同的端口号(如9090、9091、9092等),并通过Docker容器分别…...
Python自动化脚本:从零构建《三国杀》钓鱼辅助
1. 环境准备:搭建自动化钓鱼的基石 想要实现《三国杀》钓鱼自动化,首先需要搭建一个稳定的开发环境。我推荐使用雷电模拟器9作为游戏运行平台,它不仅对Android游戏兼容性好,而且提供了丰富的调试功能。记得在安装时选择非vivo手机…...
智能体AI崛起:本体论如何赋能药物研发新纪元?——2026智能体年深度解析
智能体AI作为生成式AI的进化方向,赋予AI决策和行动能力,在生命科学领域应用前景广阔。本文探讨了智能体AI的定义、架构及应用,重点分析了本体论如何通过语义标准化和跨系统映射,解决智能体在处理复杂科学知识、实现跨语言和系统语…...
从预测到归因:手把手教你用因果森林(grf)做特征重要性分析与亚组发现
从预测到归因:手把手教你用因果森林(grf)做特征重要性分析与亚组发现 在金融风控、个性化营销和医疗疗效评估等领域,我们常常面临一个关键问题:干预措施的效果是否存在显著差异?传统分析方法如A/B测试能告诉…...
Pixel Language Portal快速上手:无需Python基础的Streamlit镜像开箱即用
Pixel Language Portal快速上手:无需Python基础的Streamlit镜像开箱即用 1. 什么是Pixel Language Portal? Pixel Language Portal(像素语言跨维传送门)是一款基于腾讯Hunyuan-MT-7B核心引擎构建的创新翻译工具。它最大的特点是…...
《跨摄像机目标追踪技术:构建连续身份与空间一致性的关键路径》——从“身份匹配”到“空间连续”的视频智能体系重构
《跨摄像机目标追踪技术:构建连续身份与空间一致性的关键路径》——从“身份匹配”到“空间连续”的视频智能体系重构发布单位:镜像视界(浙江)科技有限公司一、问题定义:什么叫“真正的跨摄像机追踪”?在多…...
Linux内核container_of宏解析与应用
1. 理解container_of宏的核心作用在Linux内核开发中,container_of宏是一个极其重要且频繁使用的工具。它的核心功能是通过结构体成员的地址反推出整个结构体的起始地址。想象一下,你手里只有一张照片的某个局部,却能准确找到这张照片在相册中…...
像素史诗智识终端效果展示:自动提取数据关键指标并生成结论段落
像素史诗智识终端效果展示:自动提取数据关键指标并生成结论段落 1. 产品概览:当科研遇上像素冒险 像素史诗智识终端(Pixel Epic Wisdom Terminal)是一款颠覆传统的研究报告辅助工具。它将枯燥的数据分析过程转化为一场充满像素美学的RPG冒险࿰…...
别再死磕状态机了!用Verilog实现I2C主机/从机,这份可综合代码直接拿去用
实战派Verilog I2C实现:模块化设计到上板调试全指南 在FPGA和数字IC开发中,I2C协议因其简洁的两线制接口(SCL时钟线和SDA数据线)而广受欢迎。但当工程师真正需要在项目中实现I2C功能时,往往会陷入状态机调试的泥潭——…...
CVPR 2025新作SAGE实战:用SAM语义先验+知识蒸馏,搞定红外与可见光图像融合
SAGE实战指南:如何将CVPR 2025前沿成果落地红外与可见光图像融合项目 在计算机视觉领域,多模态图像融合技术正经历着从传统方法到深度学习驱动的范式转变。2025年CVPR会议提出的SAGE(Semantic-Aware Guided Enhancement)方法&…...
Ubuntu 20.04 无头服务器福音:5分钟搞定虚拟显示器,让NoMachine远程桌面丝滑如本地
Ubuntu 20.04 无头服务器虚拟显示器终极配置指南 当你面对一台没有物理显示器的Ubuntu服务器时,远程桌面连接往往会遇到各种令人抓狂的问题——黑屏、卡顿、分辨率异常。作为长期管理分布式服务器的运维工程师,我深刻理解这种困境对工作效率的影响。本文…...
