.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)
 *          // 不使用 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()

查看执行结果:

文章转载自: ++sq1201++

原文链接: .NET8.0多线程编码结合异步编码示例 - sq1201 - 博客园

体验地址: 引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

相关推荐
Nil2088 小时前
leetcode 300最长递增子序列
算法·leetcode·职场和发展
thefool1122669 小时前
多线程 4
java
Rain的Java大神之路9 小时前
[特殊字符]8年Java老兵转型AI Agent:90%的人挂在同一个坑,根本不用学Python!(万字实战复盘,建议收藏)
java·数据库·人工智能·后端·python·spring·ai编程
垆边人似月.9 小时前
华为机试题 :最大数
c++·算法·华为
高级程序源9 小时前
springboot大学生体测系统72170-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·django·课程设计
IT研究室9 小时前
最新计算机毕业设计选题推荐-基于spring boot的文学名著分享系统-网站-文档指导-Java-springboot
java·spring boot·课程设计
denlaku9 小时前
JDK 13 新特性详解
java·开发语言
秋饼9 小时前
Java 后端企业级 LLM 网关实战:Spring Cloud Gateway 构建统一大模型接入层
java·ai·技术分享·后端开发
今年下半年9 小时前
【防重放】Spring Boot 通过自定义注解实现接口防重放
java·spring boot·自定义注解·防重放
WeiXin_DZbishe10 小时前
基于Node.js的马拉松赛事管理系统的设计与实现-计算机毕设 附源码【课程设计】90211
java·javascript·vue.js·python·php·课程设计