C# Task任务详解

news/2024/11/30 18:44:40/

文章目录

  • 前言
  • 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还可以和委托一起使用,对程序的运行有更强的把控力。


http://www.ppmy.cn/news/1129161.html

相关文章

电脑显示系统错误怎么办?

有时我们在开机时会发现电脑无法开机&#xff0c;并显示系统错误&#xff0c;那么这该怎么办呢&#xff1f;下面我们就一起来了解一下。 方法1. 替换SAM文件解决问题 1. 重启电脑并进入安全模式。 Win8/10系统&#xff1a;在启动电脑看到Windows标志时&#xff0c;长按电源键…

VS编译器常见的错误

以上问题在编译器中出现可以在编译器中最上面加入&#xff1a; #define_CRT_SECURE_NO_WARNINGS 或者将scanf修改为scanf_s 一定要在最上端&#xff01;&#xff01;&#xff01;最上端&#xff01;&#xff01;&#xff01;最上端加入&#xff01;&#xff01;&#xff01; 虽…

成都瀚网科技:抖音上线地方方言自动翻译功能

为了让很多方言的地域历史、文化、习俗能够以短视频的形式生产、传播和保存&#xff0c;解决方言难以被更多用户阅读和理解的问题&#xff0c;平台正式上线推出当地方言自动翻译功能。创作者可以利用该功能&#xff0c;将多个方言视频“一键”转换为普通话字幕供大众观看。 具体…

K8S-EverNote同步

Node污点 释义看文档就好 https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/ 污点是Node的属性 容忍度是Pod的属性 用来标记各自特征的&#xff0c;通常协同工作。 举个例子&#xff0c; 一个Node的污点 kubectl taint nodes node1 key1v…

箱讯科技成功闯入第八届“创客中国”全国总决赛—在国际物流领域一枝独秀

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 2023年9月26日&#xff0c;第八届“创客中国”数字化转型中小企业创新创业大赛决赛在贵州圆满收官。 经过初赛、复赛、决赛的激烈角逐&#xff0c;箱讯科技与众多强劲对手同台竞技&#xff0c;最终凭借出…

K8sGPT,基于 AI 的云原生终极工具

随着人工智能和机器学习的兴起&#xff0c;企业和组织越来越多地寻找创新方法来利用这些技术来获得竞争优势。 该领域最强大的工具之一便是 K8sGPT&#xff0c;即基于 Kubernetes 的 GPT&#xff0c;它将 Kubernetes 编排的优势与 GPT 模型的高级自然语言处理能力结合在一起。 …

Spring工具类--ReflectUtils的使用

原文网址&#xff1a;Spring工具类系列--ReflectUtils的使用_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Spring的ReflectUtils的使用。 ReflectUtils工具类的作用&#xff1a;便利地进行反射操作。 Spring还有一个工具类&#xff1a;ReflectionUtils&#xff0c;它们在功能上…

多叉树+图实现简单业务流程

文章目录 场景整体架构流程业务界面技术细节小结 场景 这次遇到一个需求,大致就是任务组织成方案,方案组织成预案,预案可裁剪调整.预案关联事件等级配置,告警触发预案产生事件.然后任务执行是有先后的,也就是有流程概念. 整体架构流程 方案管理、预案管理构成任务流程的基础条…