C# Task总结(异步操作+并行)
任务Task与线程Thread不可比。Task是为了利用多CPU多核的机制而将一个大任务不断分解成小任务,这些任务具体由哪一个线程或当前线程执行由OS来决定。如果你想自己控制由哪一个Thread执行,要么自己定议task的scheduling, 要么自己来创建Thread来执行代码。
1)task是根据自己需要调用线程
2)thread就是个基本单位
简单地du说,thread是单核多线程,task是多核多线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /// <summary> /// 简单的task创建方式演示 /// </summary> private static void TaskCreatFun() { // 其一、通过传统的 new 方式来实例化一个task对象,这种方式需要手动通过start来启动 Task newTask = new Task(() => { Thread.Sleep(1000); Console.WriteLine($ "Hello Engineer, 我是 new 的一个task,线程ID:Thread.CurrentThread.ManagedThreadId}" ); }); // 启动 tsak newTask.Start(); // 其二、通过工厂 factory 来生成一个task对象,并自启动 Task factoryTask = Task.Factory.StartNew(() => { Thread.Sleep(1000); Console.WriteLine($ "Hello Engineer, 我是 factory 生产 的一个task,线程ID:Thread.CurrentThread.ManagedThreadId}" ); }); // 其三、通过 Task.Run(Action action) 来创建一个自启动task Task runTask = Task.Run(() => { Thread.Sleep(1000); Console.WriteLine($ "Hello Engineer, 我是 Task.Run 创建一个自启动task,线程ID:Thread.CurrentThread.ManagedThreadId}" ); }); runTask.RunSynchronously(); Console.WriteLine($ "Hello Engineer, 我是主线程啦!线程ID{Thread.CurrentThread.ManagedThreadId}" ); } |
Task回调
a.某一个任务结束回调
1 2 3 4 | taskList.Add(taskFactory.StartNew(() => this .DoSomethingLong( "btnTask_Click_002" ))); taskList.Add(taskFactory.StartNew(() => this .DoSomethingLong( "btnTask_Click_001" ))); //回调ContinueWhenAny没有那么精准,不一定是在某个线程完成之后发生 taskList.Add(taskFactory.ContinueWhenAny(taskList.ToArray(), t => Console.WriteLine($ "ContinueWhenAny {Thread.CurrentThread.ManagedThreadId.ToString(" 00 ")}" ))); |
b.所有任务结束回调
1 | taskList.Add(taskFactory.ContinueWhenAll(taskList.ToArray(), tList => Console.WriteLine($ "这里是ContinueWhenAll {Thread.CurrentThread.ManagedThreadId.ToString(" 00 ")}" ))); |
c.单个任务结束回调
1 | Task task2 = taskFactory.StartNew(t => this .DoSomethingLong( "btnTask_Click_005" ), "煎饼果子" ).ContinueWith(t => Console.WriteLine($ "这里是{t.AsyncState}的回调" )); |
Task等待
1 2 3 | Task.WaitAny(taskList.ToArray()); //卡界面 Task.WaitAll(taskList.ToArray()); //卡界面 |
Task获取返回结果
1 2 3 | Task< int > intTask = taskFactory.StartNew(() => 123); int iResult = intTask.Result;Task< string > intTask = taskFactory.StartNew(() => "123" ); int iResult = intTask.Result; |
Task同步执行
可以用task.RunSynchronously() 来同步执行,但是这种方式执行,只有通过new 实例化的task才有效,原因也很简单,其他两种方式创建task都已经自启动执行了,不可能在来一个同步启动执行吧。
也可以通过task.wait()来变相的实现同步执行效果,当然也可以用task.Result来变现的实现,原理很简单,因为wait()和Result都是要阻塞主流程,直到task执行完毕
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?