文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C#并发编程之Task类怎么使用

2023-07-05 16:28

关注

这篇文章主要介绍了C#并发编程之Task类怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#并发编程之Task类怎么使用文章都会有所收获,下面我们一起来看看吧。

Task.Run

Task是建立在线程池之上的一种多线程技术,它的出现使Thread成为历史。其使用方法非常简单,下面在顶级语句中做一个简单的例子

void printN(string name){    for (int i = 0; i < 3; i++)    {        Console.WriteLine($"{name}:{i}");        Task.Delay(1000).Wait();    }}Task.Run(() => printN("t1"));Task.Run(() => printN("t2"));Task.Run(() => printN("t3")).Wait();

运行后,命令行中的结果为

t3:0
t2:0
t1:0
t2:1
t3:1
t1:1
t1:2
t2:2
t3:2

Task.Run通过输入一个委托,创建一个任务并执行,同时返回一个Task对象。

Task在执行过程中,并不会等待命令行的主线程,所以在最后启动的Task后跟上Wait,即等待该线程结束之后,主线程才结束,从而让printN的输出内容得以在终端中显示。

Task类

上面的Task.Run的案例也可以用Task来实现,但Task对象创建后,并不会马上运行,而会在Start()之后运行,示例如下

void printN(object name){    for (int i = 0; i < 3; i++)    {        Console.WriteLine($"{name}:{i}");        Task.Delay(1000).Wait();    }}Action<object> act = (object name) => printN(name);Task t1 = new Task(()=>printN("t1"));new Task(act, "t2").Start();Task t3 = new Task(act, "t3");t1.Start();t3.Start();t3.Wait();

返回值

除了Task,C#还提供了带有返回值的封装,即Task<TResult>,可通过泛型的方式声明返回值。

但是,Task说到底还是个类,而非函数,这个返回值并不会在构造函数中体现出来,也不经过Start()函数,若想使用这个返回值,需要经由ContinueWith函数。

ContinueWith的功能是在某一个线程执行完毕之后,开启下一个线程。如果执行完毕的线程有返回值的话,那么ContinueWith也可以利用这个返回值。

其调用方法为

Task<int> task = new Task<int>(() =>{    Console.WriteLine("这里是task");    return 100;});//任务完成时执行处理。Task cwt = task.ContinueWith(t =>{    Console.WriteLine($"这里是Continue,task返回值为{t.Result}");});task.Start();cwt.Wait();

其中,cwt需要等待task执行完毕之后再执行。

等待和延续

在前面的案例中,已经讲解了基本的等待函数Wait和基本的延续函数ContinueWith。C#中提供了更多的等待与延续函数,以更加灵活地操作线程列表。


阻塞主线程不阻塞主线程
任意线程执行完毕即可执行WaitAnyWhenAny
所有线程执行完毕方可执行WaitAllWhenAll

其中, WhenAny, WhenAll需要与ContinueWith配合食用,当WhenXX结束之后,即执行ContinueWith中的内容,这个过程并不阻塞主线程。

为了验证这些函数的功能,先创建一个线程列表

Action<string, int> log = (name, time) =>{    Console.WriteLine($"{name} Start...");    Task.Delay(time).Wait();    Console.WriteLine($"{name} Stop!");};Task[] tasks = new Task[]{    Task.Run(() => log("A",3000)),    Task.Run(() => log("B",1000)),    Task.Run(() => log("C",2000))};

然后依次执行这几个等待函数,看看结果

Task.WaitAny(tasks); 此时当B执行完毕之后,阻塞就结束了,从而主线程结束。

B Start...
A Start...
C Start...
B Stop!

Task.WaitAll(tasks); 这次当所有线程执行完毕之后,程序才结束。

A Start...
B Start...
C Start...
B Stop!
C Stop!
A Stop!

下面这两组测试,现象和前两组相似,区别无非是在后面加上一段字符串而已。

Task.WhenAny(tasks).ContinueWith(x => Console.WriteLine($"某个Task执行完毕")).Wait();Task.WhenAll(tasks.ToArray()).ContinueWith(x => Console.WriteLine("所有Task执行完毕")).Wait();

取消任务

C#提供了CancellationToken作为Task取消的标识,通过调用Cancel()函数,可将其取消标志更改为True,从而在线程执行过程中,起到取消线程的作用。

首先创建一个可以取消的线程函数

int TaskMethod(string name, int seconds, CancellationToken token){    Console.WriteLine($"{name} 正在运行");    for (int i = 0; i < seconds; i++)    {        Task.Delay(1000).Wait();        Console.WriteLine($"{name}: {i}s");        if (token.IsCancellationRequested)            return -1;    }    return 1;}

功能很简单,就是跑循环,在跑循环的过程中,如果token指明取消,则线程结束。

下面测试一下

var cts = new CancellationTokenSource();var task = new Task<int>(() => TaskMethod("Task 1", 5, cts.Token), cts.Token);Console.WriteLine($"线程状态:{task.Status}");task.Start();Console.WriteLine($"线程状态:{task.Status}");Task.Delay(3000).Wait();cts.Cancel();Console.WriteLine($"线程状态:{task.Status}");Task.Delay(1000).Wait();Console.WriteLine($"线程状态:{task.Status}");

效果为如下

线程状态:Created
线程状态:WaitingToRun
Task 1 正在运行
Task 1: 0s
Task 1: 1s
线程状态:Running
Task 1: 2s
线程状态:RanToCompletion

在整个线程执行的过程中,共出现了四种状态

关于“C#并发编程之Task类怎么使用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C#并发编程之Task类怎么使用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯