C# Task任务详解
文章目录
- 前言
- Task
- 返回值
- 无参返回
- 有参返回
- async和await
- 返回值
- await搭配使用
- Main async改造
- Task进阶
- Task线程取消
- 测试用例
- 超时设置
- 线程暂停和继续
- 测试用例
- 多任务等最快
- 多任务全等待
- 结论
前言
Task是对于Thread的封装,是极其优化的设计,更加方便了我们如何操控线程
Task
Task声明形如:
public static Task Sleep()
{}
Task是一种类型
返回值
直接声明Task是需要返回值的。

无参返回
public static Task Sleep(int second)
{return Task.CompletedTask;
}
有参返回
public static Task<T> Sleep(){return Task.FromResult(T);}
//举例,返回参数只能唯一,除非使用元祖public static Task<string> Sleep(){return Task.FromResult("Hello world!");}
使用Task.Result获取返回值
var res = Sleep().Result;
async和await
async和await是对于异步事件的控制,方便我们对异步事件的操控。
返回值
使用async之后可以直接设置返回值
///有参返回public static async Task<string> Sleep(){return "Hello world";}///无参返回public static async Task Sleep(){}
await搭配使用
异步事件的等待使用await方法
public static async Task Sleep(int second){await Task.Delay(second * 1000);Console.WriteLine($"等待{second}s");}static void Main(string[] args){Sleep(3);Sleep(2);Sleep(1);Console.WriteLine("运行完毕");//使用键盘键入事件阻塞主进程,主进程结束程序会立即退出Console.ReadKey();}
打印结果:

打印结果显示:
- 同步事件先结束
- 异步事件互相不阻塞,3,2,1同时开始,等待3,2,1s打印1,2,3。
Main async改造
主程序是Void,无法等待

将Void改成Task,即可等待异步事件

打印结果服务预期,等待异步事件结束后运行

Task进阶
C#Task取消任务执行CancellationTokenSource
C# Task 暂停与取消
Task线程取消
以前Thread有Abort()方法,强行销毁线程,但是这个方法用于极大的安全问题,已经被弃用。

线程不能直接被销毁,只能通过抛出异常来取消线程。
//声明token
var tokenSource = new CancellationTokenSource();
//注册异常抛出
tokenSource.Token.ThrowIfCancellationRequested();
//注册取消事件回调
tokenSource.Token.Register(() =>
{Console.WriteLine("线程已被取消");
});。。。。。。别的地方的代码
//取消token,那么之前写ThrowIfCancellationRequested的地方会直接结束
tokenSource.Cancel();
测试用例
一个简单的死循环函数,运行时返回token,用于直接跳出程序
static async Task Main(string[] args)
{var token = Loop();//等待3s抛出异常await Task.Delay(1000 * 3);Console.WriteLine("任务完成!");token.Cancel();Console.ReadKey();}/// <summary>
/// 循环等待
/// </summary>
/// <returns></returns>
public static CancellationTokenSource Loop()
{var tokenSource = new CancellationTokenSource();Console.WriteLine("任务开始!");tokenSource.Token.Register(() =>{Console.WriteLine("线程已被取消");});var count = 0;Task.Run(async () =>{while (true){await Task.Delay(1000);//抛出异常,直接结束线程tokenSource.Token.ThrowIfCancellationRequested();count++;Console.WriteLine(count);}});return tokenSource;
}
打印结果

这样使用起来也更加安全。
超时设置
tokenSource.CancelAfter是超时方法。
CancelAfter(1000):1000毫秒后超时
static async Task Main(string[] args){var token = Loop();///3000毫秒后取消token.CancelAfter(1000*3);Console.ReadKey();}/// <summary>/// 循环等待/// </summary>/// <returns></returns>public static CancellationTokenSource Loop(){var tokenSource = new CancellationTokenSource();Console.WriteLine("任务开始!");tokenSource.Token.Register(() =>{Console.WriteLine("线程已被取消");});var count = 0;Task.Run(async () =>{while (true){await Task.Delay(1000);tokenSource.Token.ThrowIfCancellationRequested();count++;Console.WriteLine(count);}});return tokenSource;}
线程暂停和继续
线程暂停也是使用一个类去控制,ManualResetEvent。和线程销毁一样,是不能直接暂停的,因为直接暂停也不安全。
//声明,false为默认阻塞,true为不阻塞
var resetEvent = new ManualResetEvent(false);
//暂停,通过WaitOne方法来阻塞线程,通过Set和Reset来设置是否阻塞
resetEvent.WaitOne();
//阻塞暂停
resetEvent.Set()
//取消阻塞,继续
resetEvent.Reset()
测试用例
static async Task Main(string[] args){var canStop = CanStop();//等待3s抛出异常Console.WriteLine("等待3s启动");await Task.Delay(1000 * 3);Console.WriteLine("启动!");canStop.Set();Console.WriteLine("等待3s暂停");await Task.Delay(3000);Console.WriteLine("暂停!");canStop.Reset();Console.ReadKey();}public static ManualResetEvent CanStop(){var resetEvent = new ManualResetEvent(false);var count = 0;Task.Run(async () =>{while (true){resetEvent.WaitOne();await Task.Delay(1000);count++;Console.WriteLine(count);}});return resetEvent;}
多任务等最快
await Task.WhenAny(Task1,Task2,Task3)
只会等待最快的一个。
static async Task Main(string[] args){await Task.WhenAny(Sleep(1),Sleep(2),Sleep(3));Console.WriteLine("运行结束");Console.ReadKey();}public async static Task Sleep(int second){await Task.Delay(second*1000);Console.WriteLine($"等待{second}s");}
运行结果

多任务全等待
static async Task Main(string[] args){await Task.WhenAll(Sleep(1), Sleep(2), Sleep(3));Console.WriteLine("运行结束");Console.ReadKey();}public async static Task Sleep(int second){await Task.Delay(second*1000);Console.WriteLine($"等待{second}s");}

结论
异步线程的控制是极其重要的内容,Task还可以和委托一起使用,对程序的运行有更强的把控力。
相关文章:
C# Task任务详解
文章目录 前言Task返回值无参返回有参返回 async和await返回值await搭配使用Main async改造 Task进阶Task线程取消测试用例超时设置 线程暂停和继续测试用例 多任务等最快多任务全等待 结论 前言 Task是对于Thread的封装,是极其优化的设计,更加方便了我…...
百度网盘的扩容
百度网盘的扩容怎么扩 百度网盘的扩容通常需要购买额外的存储空间。以下是扩容百度网盘存储空间的一般步骤: 登录百度网盘:首先,在您的计算机或移动设备上打开百度网盘,并使用您的百度账号登录。 选择扩容选项:一旦登…...
Android 悬浮窗
本文参考文章地址:https://juejin.cn/post/7009180088310693919 一、申请权限 <uses-permission android:name"android.permission.SYSTEM_ALERT_WINDOW" />二、创建悬浮窗service <serviceandroid:name".FloatingWindowService"an…...
3.物联网射频识别,(高频)RFID应用ISO14443-2协议
一。ISO14443-2协议简介 1.ISO14443协议组成及部分缩略语 (1)14443协议组成(下面的协议简介会详细介绍) 14443-1 物理特性 14443-2 射频功率和信号接口 14443-3 初始化和防冲突 (分为Type A、Type B两种接口&…...
数据分析笔记1
数据分析概述:数据获取--探索分析与可视化--预处理--分析建模--模型评估 数据分析含义:利用统计与概率的分析方法提取有用的信息,最后进行总结与概括 一、数据获取 实用网站:kaggle 阿里云天池 数据仓库:将所有业务数据…...
paramiko 3
import paramiko import concurrent.futuresdef execute_remote_command(hostname, username, password, command):try:# 创建SSH客户端client paramiko.SSHClient()client.set_missing_host_key_policy(paramiko.AutoAddPolicy())# 使用密码认证连接远程主机client.connect(h…...
基于Dlib训练自已的人脸数据集提高人脸识别的准确率
前言 由于图像的质量、光线、角度等因素影响。这时如果使用官方提供的模型做人脸识别,就会导至识别率不是很理想。人脸识别的准确率与图像的清晰度和质量有关。如果图像模糊、光线不足或者有其他干扰因素,Dlib 可能无法正确地识别人脸。为了确保图像质量…...
Git 详细安装教程(详解 Git 安装过程的每一个步骤
Git 详细安装教程(详解 Git 安装过程的每一个步骤) 该文章详细具体,值得收藏学习...
kafka伪集群部署,使用KRAFT模式
1:拉去管理kafka界面UI镜像 docker pull provectuslabs/kafka-ui2:拉去管理kafka镜像 docker pull bitnami/kafka3:docker-compose.yml version: 3.8 services:kafka-1:container_name: kafka1image: bitnami/kafka ports:- "19092:19092"- "19093:19093&quo…...
【双指针遍历】N数之和问题
文章目录 二数之和LC1三数之和LC15四数之和LC18最接近的三数之和LC16 二数之和LC1 题目链接 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对…...
Qt的QObject类
文章目录 QObject类如何在Qt中使用QObject的信号与槽机制?如何在Qt中使用QObject的属性系统?QObject的元对象系统如何实现对象的反射功能? QObject类 Qt的QObject类是Qt框架中的基类,它是所有Qt对象的父类。QObject提供了一些常用…...
【图论C++】链式前向星(图(树)的存储)
/*** file * author jUicE_g2R(qq:3406291309)————彬(bin-必应)* 一个某双流一大学通信与信息专业大二在读 * * brief 一直在竞赛算法学习的路上* * copyright 2023.9* COPYRIGHT 原创技术笔记:转载需获得博主本人…...
16.PWM输入捕获示例程序(输入捕获模式测频率PWMI模式测频率和占空比)
目录 输入捕获相关库函数 输入捕获模式测频率 PWMI模式测频率和占空比 两个代码的接线图都一样,如下 测量信号的输入引脚是PA6,信号从PA6进来,待测的PWM信号也是STM32自己生成的,输出引脚是PA0。 需要配置电路连接图示如下&…...
pip version 更新
最近报了一个错: 解决办法: 在cmd输入“conda install pip” conda install pip 完了之后再输入: python -m pip install --upgrade pip ok....
Oracle - 多区间按权重取值逻辑
啰嗦: 其实很早就遇到过类似问题,也设想过,不过一致没实际业务需求,也就耽搁了;最近有业务提到了,和同事讨论,各有想法,所以先把逻辑整理出来,希望有更好更优的解决方案;…...
本次CTF·泰山杯网络安全的基础知识部分(二)
简记23年九月参加的泰山杯网络安全的部分基础知识的题目,随时补充 15(多选)网络安全管理工作必须坚持“谁主管、谁负责,谁运营、谁负责,谁使用、谁负责”的原则,和“属地管理”的原则 谁主管、谁负责&…...
MyBatis 映射文件(Mapper XML):配置与使用
MyBatis 映射文件(Mapper XML):配置与使用 MyBatis是一个强大的Java持久化框架,它允许您将SQL查询、插入、更新和删除等操作与Java方法进行映射。这种映射是通过MyBatis的映射文件,通常称为Mapper XML文件来实现的。本…...
基于 SpringBoot 的大学生租房网站
文章目录 1 简介2 技术栈3 需求分析4 系统设计5 系统详细设计5.1系统功能模块5.2管理员模块5.3房主功能模块5.4用户功能模块 源码咨询 1 简介 本大学生租房系统使用简洁的框架结构,专门用于用户浏览首页,房屋信息,房屋评价,公告资…...
BL808学习日志-0-概念理解
一、主核心的介绍 1.三个核心在FREERTOS系统中相互独立,各负责各自的外设和程序;其中M0和LP核心在一个总线上,D0单独在一个总线上,两个总线使用AXI4.0(??)通讯? CPU0(M0)-E907架构,320MHz; CPU1(LP)-E9…...
CISSP学习笔记:业务连续性计划
第三章 业务连续性计划 3.1 业务连续性计划 业务连续性计划(BCP): 对组织各种过程的风险评估,发生风险的情况下为了使风险对组织的影响降至最小而定制的各种计划BCP和DRP首先考虑的人不受伤害,然后再解决IT恢复和还原问题BCP的主要步骤: 项…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
