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多线程编码结合异步编码示例的更多相关文章

  1. 多线程异步编程示例和实践-Task

    上篇博文中,我们介绍了Thread和ThreadPool: 多线程异步编程示例和实践-Thread和ThreadPool 本文中我们继续,说一下TPL(Task Parallel Library, 简 ...

  2. Swift3.0语言教程获取字符串编码与哈希地址

    Swift3.0语言教程获取字符串编码与哈希地址 Swift3.0语言教程获取字符串编码与哈希地址,以下将讲解字符串中其它内容的获取方法. 1.获取字符串编码 在NSString中可以使用2个属性获取 ...

  3. JavaScript学习笔记(六)—— 异步编码

    第七章 异步编码 1  事件处理程序 处理程序:即网页加载完毕后将执行的代码,称回调函数或监听器: 包含:处理函数+window.onload=函数名; <script language=&qu ...

  4. 各种编码问题产生原因以及解决办法---------响应编码,请求编码,URL编码

     响应编码 产生原因以及解决办法: 示例: package cn.yzu; import java.io.IOException; import javax.servlet.ServletExcept ...

  5. Gamma编码及Delta编码概述

    一.Elias Gamma Coding 即Gamma编码,是一种对正整数进行编码的统一编码,由Peter Elias发明.适用于预先无法获知最大编码整数的情况,而且小整数出现频率高,大整数出现频率低 ...

  6. UTF-8和GBK编码之间的区别(页面编码、数据库编码区别)以及在实际项目中的应用

    第一节:UTF-8和GBK编码概述 UTF-8 (8-bit Unicode Transformation Format) 是一种针对Unicode的可变长度字符编码,又称万国码,它包含全世界所有国家 ...

  7. Android硬编码——音频编码、视频编码及音视频混合

    视频编解码对许多Android程序员来说都是Android中比较难的一个知识点.在Android 4.1以前,Android并没有提供硬编硬解的API,所以之前基本上都是采用FFMpeg来做视频软件编 ...

  8. 【字符编码】字符编码 && Base64编码算法

    一.前言 在前面的解决乱码的一文中,只找到了解决办法,但是没有为什么,说白了,就是对编码还是不是太熟悉,编码问题是一个很简单的问题,计算机从业人员应该也必须弄清楚,基于编码的应用有Base64加密算法 ...

  9. cnless.sh:改进版less,可自动识别GBK编码或UTF-8编码。

    #!/bin/bash #功能:让GBK编码的文件可以使用less正常显示中文(自动识别GBK和UTF-8编码) #v0. 在LINUX下,使用UTF-8编码,less UTF-8的文件时显示中文正常 ...

  10. HTTP 协议中的 Content-Encoding 和 Transfer-Encoding(内容编码和传输编码)

    转自:http://network.51cto.com/art/201509/491335.htm Transfer-Encoding,是一个 HTTP 头部字段,字面意思是「传输编码」.实际上,HT ...

随机推荐

  1. js实现浏览器后退页面刷新

    最近在开发中遇到一个问题: 在一个列表页面,点击进入详情,详情页面对其状态操作,其详情页面有做修改,然后点击浏览器后退,返回到列表页,在列表页面状态还是操作之前的,为解决状态统一需要手动刷新改列表页. ...

  2. 低功耗4G模组:Air780EP开发板RC522实例

    ​ 本文讲解合宙Air780EP开发板RC522实例,文末[阅读原文]获取最新资料. 本文档适用于Air780EP开发板 关联文档和使用工具 LuatOS-Soc固件获取 https://gitee. ...

  3. 手搓党分享:用Air700E开发板+毫米波雷达,搓一个睡眠监测仪!

    ​ 只能说,看到这个大佬分享的睡眠监测仪,手上的手环瞬间不香了... 用Air700E开发板+毫米波雷达,手搓一个开箱即用的睡眠监测仪,不花冤枉钱! 一.项目原理及硬件制作 毫米波是指频率范围从30- ...

  4. 超级干货:Air780E之RS485通信篇,你学会了吗?

    ​ 今天,我们来学习低功耗4G模组Air780E的RS485通信,同学们,你学习了吗? 一.RS485简介  物联网(IoT)在工业场景中的应用越来越广泛,而RS485是一种常见的通信协议,广泛应用于 ...

  5. 3张大图剖析HttpClient和IHttpClientFactory在解决DNS解析问题上的殊途同归

    在开发者便利度角度,我们很轻松地使用HttpClient对象发出HTTP请求,只需要关注应用层协议的BaseAddr.Url.ReqHeader.timeout. 实际在HttpClient在源码级别 ...

  6. 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-5-创建首个自动化脚本(详细教程)

    1.简介 前面几篇宏哥介绍了两种(java和maven)环境搭建和浏览器的启动方法,这篇文章宏哥将要介绍第一个自动化测试脚本.前边环境都搭建成功了,浏览器也驱动成功了,那么我们不着急学习其他内容,首先 ...

  7. CodeForces - 1353D Constructing the Array

    CodeForces - 1353D 这道题也可能比较简单,主要是要想到优先队列要怎么使用,这一点如果用递归会写不了 但是因为对优先队列不太熟悉,只有被提示可以用优先队列才想到要怎么用, 还是很重要的 ...

  8. 程序员遇到bug时常见的30种反应

    开发应用程序是一项压力很大的工作,人无完人,工作中遇到bug是很正常的事,有些程序员会生气,沮丧,郁闷,甚至泄气,也有一些程序员则会比较淡定.如何进行修复bug的过程,是值得我们好好推敲的. 我想分享 ...

  9. elasticsearch之python操作(非原生)

    elasticsearch 模块 Elasticsearch低级客户端.提供从Python到ES REST端点的直接映射. 连接集群节点 指定连接 es = Elasticsearch( ['172. ...

  10. 规范LR(1)语法分析表

    前面已经实现了SLR语法分析表,但是可能会出现即使语法不是二义性文法,也存在移入/规约冲突 状态 i 包含项[A ->α ],当状态 i 出现在栈顶时,栈中的可行前缀时βα且在任何最后句型中a都 ...