.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、也可以使用如下方法,手动开启任务

6、查看执行结果

7、如果需要等待子线程执行完毕,才执行后续操作,可以使用Wait()来实现


PS:等待子线程执行指定的时间,可以通过使用 Wait(毫秒数) 来实现
8、也可以使用Task.Factory创建一个任务工厂来实现

9、查看执行结果

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)
* // 不使用 Unwrap
var task1 = factory.StartNew(async () => {
await Task.Delay(1000);
return "Hello";
});
// task1 的类型是 Task<Task<string>>
// 需要两次 await
string result1 = await (await task1);
---------------------------------------------------
// 使用 Unwrap
var task2 = factory.StartNew(async () => {
await Task.Delay(1000);
return "Hello";
}).Unwrap();
// task2 的类型是 Task<string>
// 只需要一次 await
string 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()

查看执行结果:

.NET8.0多线程编码结合异步编码示例的更多相关文章
- 多线程异步编程示例和实践-Task
上篇博文中,我们介绍了Thread和ThreadPool: 多线程异步编程示例和实践-Thread和ThreadPool 本文中我们继续,说一下TPL(Task Parallel Library, 简 ...
- Swift3.0语言教程获取字符串编码与哈希地址
Swift3.0语言教程获取字符串编码与哈希地址 Swift3.0语言教程获取字符串编码与哈希地址,以下将讲解字符串中其它内容的获取方法. 1.获取字符串编码 在NSString中可以使用2个属性获取 ...
- JavaScript学习笔记(六)—— 异步编码
第七章 异步编码 1 事件处理程序 处理程序:即网页加载完毕后将执行的代码,称回调函数或监听器: 包含:处理函数+window.onload=函数名; <script language=&qu ...
- 各种编码问题产生原因以及解决办法---------响应编码,请求编码,URL编码
响应编码 产生原因以及解决办法: 示例: package cn.yzu; import java.io.IOException; import javax.servlet.ServletExcept ...
- Gamma编码及Delta编码概述
一.Elias Gamma Coding 即Gamma编码,是一种对正整数进行编码的统一编码,由Peter Elias发明.适用于预先无法获知最大编码整数的情况,而且小整数出现频率高,大整数出现频率低 ...
- UTF-8和GBK编码之间的区别(页面编码、数据库编码区别)以及在实际项目中的应用
第一节:UTF-8和GBK编码概述 UTF-8 (8-bit Unicode Transformation Format) 是一种针对Unicode的可变长度字符编码,又称万国码,它包含全世界所有国家 ...
- Android硬编码——音频编码、视频编码及音视频混合
视频编解码对许多Android程序员来说都是Android中比较难的一个知识点.在Android 4.1以前,Android并没有提供硬编硬解的API,所以之前基本上都是采用FFMpeg来做视频软件编 ...
- 【字符编码】字符编码 && Base64编码算法
一.前言 在前面的解决乱码的一文中,只找到了解决办法,但是没有为什么,说白了,就是对编码还是不是太熟悉,编码问题是一个很简单的问题,计算机从业人员应该也必须弄清楚,基于编码的应用有Base64加密算法 ...
- cnless.sh:改进版less,可自动识别GBK编码或UTF-8编码。
#!/bin/bash #功能:让GBK编码的文件可以使用less正常显示中文(自动识别GBK和UTF-8编码) #v0. 在LINUX下,使用UTF-8编码,less UTF-8的文件时显示中文正常 ...
- HTTP 协议中的 Content-Encoding 和 Transfer-Encoding(内容编码和传输编码)
转自:http://network.51cto.com/art/201509/491335.htm Transfer-Encoding,是一个 HTTP 头部字段,字面意思是「传输编码」.实际上,HT ...
随机推荐
- 如果让你处理hbase 怎么保证数据的安全性可靠性 不需要具体的设置 要一套方案
有关数据安全及可靠我们认为大体上分为存储安全和使用安全 1 数据存储安全 hbase是基于hdfs的一种数据存储解决方案,所以有关数据的安全性可靠性可以利用hdfs自身的副本机制保障.另外原生的hba ...
- Windows通过修改注册表设置系统默认浏览器
前段时间有个程序要求获取系统的默认浏览器,baidu.Google了好久,后又结合procmon.exe跟踪浏览器打开web页面的注册表操作信息,找到了最终的位置,这里做一个总结.亲测win10多个浏 ...
- (Python基础教程之十六)Python multidict示例–将单个键映射到字典中的多个值
1.什么是multidict词典> 在python中," multidict "一词用于指代字典,在字典中可以将单个键映射到多个值.例如 多重结构 multidictWith ...
- Java Timer&TimerTask原理分析
如果你使用Java语言进行开发,对于定时执行任务这样的需求,自然而然会想到使用Timer和TimerTask完成任务,我最近就使用 Timer和TimerTask完成了一个定时执行的任务,实现得没有问 ...
- 从InputStream到ByteArrayInputStream
本篇主要分析:1.如何将byte数组适配至ByteArrayInputStream,对应与IO部分的适配器模式:2.BufferedInputStream的工作原理,对应于IO的装饰器模式,会首先研究 ...
- 2024-11-27:字符串的分数。用go语言,给定一个字符串 s,我们可以定义其“分数”为相邻字符的 ASCII 码差值绝对值的总和。 请计算并返回字符串 s 的分数。 输入:s = “hello“
2024-11-27:字符串的分数.用go语言,给定一个字符串 s,我们可以定义其"分数"为相邻字符的 ASCII 码差值绝对值的总和. 请计算并返回字符串 s 的分数. 输入:s ...
- 2024年值得推荐的6款 Vue 后台管理系统模板,开源且免费!
前言 在现今的软件开发领域,Vue.js凭借其高效.灵活和易于上手的特性,成为了前端开发的热门选择.对于需要快速搭建企业级后台管理系统的开发者而言,使用现成的Vue后台管理系统模板无疑是一个明智之举. ...
- 销讯通CRM系统如何管理医药代表的销售过程
医药行业的销售代表与其他行业的销售代表在专业知识要求.客户群体.销售流程.以及行业特性等方面都存在明显的区别,他们必须具备更高的专业素养和综合能力. CRM(客户关系管理系统)在医药行业中对于管理医药 ...
- 常用js 函数
过滤对象空值 removeEmptyValues(obj) { for (const key in obj) { ...
- 一个.NET开源、免费、功能强大的 PDF 处理工具
前言 在日常工作中PDF文档的处理往往受限于其固有的格式,使得用户在编辑.合并.剪裁等方面面临诸多不便.今天大姚给大家分享一个.NET开源.免费.功能强大的 PDF 处理工具:PDF 补丁丁(PDFP ...