C# async、await异步语法 +Async+Task实现斐波那契数列渲染案例
笔记承接承接Task全套笔记是多线程最后一节核心语法AsyncAwait是C#语法糖简化异步代码、解决回调地狱是目前异步编程最优写法前置学习链路Thread原生线程→ThreadPool线程池→Task异步任务→async/await语法窗体控件button1~button4分别测试异步执行、返回值、串行任务二、async与await基础语法必考2.1 两个关键字作用async修饰方法标识该方法为异步方法单独使用无任何异步效果必须配合awaitawait等待异步任务仅能写在async方法内部后面只能绑定 Task / 异步方法2.2 核心底层特性背诵await等待任务执行期间不会阻塞UI主线程让出主线程权限主线程可以继续执行其他业务异步任务执行完毕自动切回原线程继续执行await后续代码最大优势同步式代码写法实现异步编程效果代码工整规避ContinueWith多层回调混乱2.3 异步方法返回值规范void事件点击方法专用按钮点击Task无返回值异步方法TaskT带返回值异步方法T为返回数据类型三、基础同步异步方法拆分3.1 普通同步方法SayHello1、SayHello2普通同步方法代码自上而下串行执行执行完毕才执行下一行public void SayHello1() { Console.WriteLine(hello world1); } public void SayHello2() { Console.WriteLine(hello world2); }3.2 基础异步方法 SayHello3逐行拆解执行流程修正原代码模糊注释//异步方法async修饰不能单独生效 public async void SayHello3() { //1.同步代码立即执行 Console.WriteLine(dddddddddddddddddddddddddd); //2.创建并启动原生Task任务 Task t new Task(() { Console.WriteLine(hello world3); }); t.Start(); //3.异步等待让出主线程不阻塞UI //后台等待t执行完毕主线程释放可以执行其他操作 await t; //4.第一个任务完成执行第二个异步任务 await Task.Run(() { Console.WriteLine(另一个任务); }); }3.3 窗体构造方法执行顺序public Form1() { InitializeComponent(); SayHello1();//同步执行 SayHello2();//同步执行 SayHello3();//调用异步方法遇到await立刻让出主线程不阻塞构造函数 Console.WriteLine(sssssssssssss);//该行无需等待异步完成直接执行 }输出顺序hello1→hello2→dddd→sssss→hello3→另一个任务四、四大按钮案例逐行解析4.1 button1异步调用基础测试private void button1_Click(object sender, EventArgs e) { SayHello3();//调用异步方法 //无需等待异步执行完毕直接执行后续代码 Console.WriteLine(后续执行的代码); }执行特点异步代码后台运行主线程直接放行互不阻塞4.2 button2获取带返回值异步结果核心await自动解析泛型Task结果替代.Result不会阻塞线程private async void button2_Click(object sender, EventArgs e) { Taskint t1 GetResult();//调用异步方法 await t1;//等待任务执行不阻塞UI Console.WriteLine(t1.Resultssssssssssssssss); } /// summary /// 有返回值异步业务方法 /// 返回值必须声明 Task基础类型 /// /summary public async Taskint GetResult() { //启动耗时异步任务 Taskint t Task.Run(() { return 100; }); //✅await自动提取任务返回值赋值变量最优写法 int num await t; //两种取值等价await取值 / Result取值 Console.WriteLine(numsss); Console.WriteLine(t.Result); return t.Result; }4.3 button3最简取值案例简化冗余代码直观展示await取值原理private async void button3_Click(object sender, EventArgs e) { //模拟耗时异步任务 Taskint t Task.Run(() { Thread.Sleep(100); return 100; }); //await阻塞异步流程不阻塞UI主线程 int num await t; //两种方式获取返回值结果完全一致 Console.WriteLine(num); Console.WriteLine(t.Result); }4.4 button4异步任务串行顺序执行对比旧写法ContinueWith链式回调新版await串行执行代码极简、可读性极高private async void button4_Click(object sender, EventArgs e) { #region 老旧写法ContinueWith链式回调多层嵌套、代码混乱回调地狱 //Taskstring t1 new Taskstring((s) //{ // Console.WriteLine(任务1); // return t1s; //},aaaa); //t1.Start(); //Task t2 t1.ContinueWith(preTask //{ // Console.WriteLine(任务2); // Console.WriteLine(preTask.Result); //}); //Task t3 t2.ContinueWith(preTask //{ // Console.WriteLine(任务3); //}); #endregion //✅新式await串行写法自上而下顺序执行逻辑清晰 Taskstring t1 new Taskstring((s) { Console.WriteLine(任务1); return t1 s; }, aaaa); t1.Start(); string s1 await t1;//等待任务1执行完毕 Task t2 Task.Run(() { Console.WriteLine(任务2); }); await t2;//等待任务2执行完毕 Task t3 Task.Run(() { Console.WriteLine(任务3); }); await t3;//等待任务3执行完毕 }五、异步五层演进期末简答题必考Thread原生线程粒度最低手动创建销毁开销大无法管控返回值极易内存泄漏ThreadPool线程池复用线程、优化性能无法管控任务状态、获取返回值Task异步任务基于线程池封装自带状态、返回值需要ContinueWith回调代码嵌套混乱asyncawait语法糖同步代码结构实现异步逻辑解决回调地狱不阻塞UI最终演进方向Thread → ThreadPool → Task → Async/Await六、易错考点汇总单独添加async没有await没有任何异步效果依旧同步执行await只能写在async修饰的方法内部普通方法禁止使用awaitawait后方只能放置 Task、TaskT、异步方法不能写普通变量Result取值阻塞主线程await取值不阻塞UI优先使用await按钮点击事件异步返回值只能写void业务异步方法禁止写void必须返回Task七、整理完整版可运行代码using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace _3async和await { public partial class Form1 : Form { public Form1() { InitializeComponent(); SayHello1(); SayHello2(); SayHello3(); Console.WriteLine(sssssssssssss); } public void SayHello1() { Console.WriteLine(hello world1); } public void SayHello2() { Console.WriteLine(hello world2); } //可以在方法前添加async关键字 使其变成异步的方法 //如果仅仅添加async 没有异步的效果 配合await进行使用 //await是等待,后面只能跟Task或者异步方法等待异步任务执行时候再会执行到主线程里面 //async awai最大特点既有异步的特性不会阻塞使用同步代码编写方式去实现异步编程 结构更清晰 public async void SayHello3() { Console.WriteLine(dddddddddddddddddddddddddd); Task t new Task(() { Console.WriteLine(hello world3); }); t.Start(); await t;// 等待异步任务执行在等待的过程中不会阻塞主线程回到主线程去执行 await Task.Run(() { Console.WriteLine(另一个任务); }); } private void button1_Click(object sender, EventArgs e) { SayHello3(); Console.WriteLine(后续执行的代码); } private async void button2_Click(object sender, EventArgs e) { Taskint t1 GetResult(); await t1; Console.WriteLine(t1.Resultssssssssssssssss); } //返回值是 Taskint类型 public async Taskint GetResult() { // 有返回值的异步任务 Taskint t Task.Run(() { return 100; }); int num await t; //等待异步任务执行把结果取出来 Console.WriteLine(numsss); Console.WriteLine(t.Result); return t.Result; } private async void button3_Click(object sender, EventArgs e) { // 有返回值的异步任务 Taskint t Task.Run(() { Thread.Sleep(100); return 100; }); int num await t; //等待异步任务执行把结果取出来 Console.WriteLine(num); Console.WriteLine(t.Result); } private async void button4_Click(object sender, EventArgs e) { /* //异步任务按照顺序执行 Taskstring t1 new Taskstring((s) { Console.WriteLine(任务1); return t1s; },aaaa); t1.Start(); //preTask 上一个任务 t1 Task t2 t1.ContinueWith(preTask { Console.WriteLine(任务2); Console.WriteLine(preTask.Result); }); // t3在t2执行之后执行 Task t3 t2.ContinueWith(preTask { Console.WriteLine(任务3); }); */ Taskstring t1 new Taskstring((s) { Console.WriteLine(任务1); return t1 s; }, aaaa); t1.Start(); string s1 await t1; Task t2 Task.Run(() { Console.WriteLine(任务2); }); await t2; Task t3 Task.Run(() { Console.WriteLine(任务3); }); await t3; } } } /* * thread * * threadPool * * Task 和 TaskT * * Async和Await * * * */AsyncTask实现斐波那契数列渲染案例笔记承接承接async/await语法、Task进度条案例综合大题实操案例整合知识点异步语法、取消令牌、递归算法、DataGridView表格渲染、进度条联动、暂停/继续/重置窗体控件Button1启动、Button2暂停、Button3继续、Button4停止、ProgressBar进度条、DataGridView表格二、全局变量逐句释义四个全局变量管控任务、状态、计数全部为联动启停核心namespace _4例子 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //全局异步任务管控斐波那契计算任务 Task task; //暂停标记false运行、true暂停 bool pause false; //取消令牌安全管控task任务 CancellationTokenSource cts; //强制停止标记清空表格、归零进度 bool stop false; //全局计数器控制计算1~50位斐波那契数列 int i 0;三、核心入口启动按钮 button13.1 方法特征添加async修饰内部可以使用await外层while循环控制整体流程实现有序串行计算private async void button1_Click(object sender, EventArgs e) { //启动初始化清空暂停、停止状态 pause false; stop false; //循环判定三大条件 //1.不暂停 2.不强制停止 3.计算位数小于等于50 while (!pause !stop i 50) { //await等待每一位斐波那契计算完成不阻塞UI //拆分计算UI刷新异步任务 await Calc(i); //计算完成位数自增 i; } }3.2 执行逻辑循环每遍历一次计算1位斐波那契数列await Calc(i)等待单次计算页面渲染完毕再执行下一次循环全程不卡死窗体同步写法实现异步效果四、业务封装方法Calc 计算UI渲染功能创建Task异步任务、绑定取消令牌、执行斐波那契计算、刷新进度条表格/// summary /// 异步封装方法计算斐波那契 刷新UI /// 返回值Task 支持上层await等待 /// /summary public Task Calc(int data) { //每一次计算重新生成取消通行证禁止复用旧令牌 cts new CancellationTokenSource(); //实例化异步任务第二个参数data→向任务传参 task new Task(s { //取出当前计算的位数 long num Convert.ToInt64(s); //调用递归算法计算斐波那契结果 long result FiBo(num); try { //跨线程刷新UI子线程禁止直接操作控件必须Invoke Invoke(new Action(() { //进度条联动位数×2放大进度填满0~100进度条 progressBar1.Value (int)num * 2; //表格插入数据第一列位数、第二列计算结果插入首行 dataGridView1.Rows.Insert(0, new object[] { num, result }); //触发强制停止清空所有页面状态、复位计数 if (stop) { i 0; progressBar1.Value 0; dataGridView1.Rows.Clear(); } })); } catch (Exception) { //捕获UI销毁、线程冲突异常防止程序闪退 Console.WriteLine(UI渲染异常); } }, data, cts.Token);//传入参数绑定取消令牌 task.Start();//启动异步任务 return task;//返回任务供上层await接收 }五、递归算法斐波那契 FiBo5.1 算法规则斐波那契数列规则第1位、第2位数值 1后续每一位 前两位之和/// summary /// 递归实现斐波那契数列 /// /summary public long FiBo(long n) { //递归终止条件第一位、第二位直接返回1 if (n 3) { return 1; } //递归公式前一项前二项 return FiBo(n - 1) FiBo(n - 2); }5.2 课堂易错点n50递归计算量爆炸运算极慢CPU占用飙升使用long返回值int范围太小高位斐波那契数值溢出报错六、三大功能按钮解析6.1 Button2 暂停private void button2_Click(object sender, EventArgs e) { pause true;//开启暂停标记阻塞外层while循环 }6.2 Button3 继续修复原生逻辑隐患原生代码逻辑直接调用button1_Click不会重置循环但是保留原有进度继续执行缺陷极端情况产生冗余任务private void button3_Click(object sender, EventArgs e) { pause false;//关闭暂停标记放行循环 //重启触发异步循环接续原有进度执行 button1_Click(null, null); }6.3 Button4 强制停止复位private void button4_Click(object sender, EventArgs e) { stop true;//开启全局停止标记 i 0;//计数器归零 progressBar1.Value 0;//清空进度条 dataGridView1.Rows.Clear();//清空表格数据 }七、原生代码Bug汇总考试改错考点递归性能漏洞第40位之后递归计算巨慢界面卡顿递归深度过高取消令牌闲置声明cts但是未调用Cancel停止任务无法销毁后台线程轻微内存泄漏继续按钮重启任务存在极小概率任务叠加未做窗体关闭资源释放后台递归常驻进程八、整体执行流程背诵版点击启动初始化状态进入while循环循环调用Calc创建异步Task绑定取消令牌后台递归计算斐波那契数列Invoke刷新进度条表格await等待单次任务结束计数器自增执行下一轮计算点击暂停pausetrue阻断循环暂停运算点击继续关闭暂停标记接续进度运算点击停止全局复位清空页面、归零计数九、核心综合考点异步嵌套async外层接收等待Task内层执行业务UI跨线程更新所有控件赋值必须包裹Invoke状态分流pause控制暂停、stop强制全局复位双层状态管控算法异步结合递归耗时业务必须放入子线程防止UI卡死十.完整代码using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace _4例子 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } Task task; bool pause false; CancellationTokenSource cts; bool stop false; int i 0; private async void button1_Click(object sender, EventArgs e) { pause false; stop false; while (!pause!stopi50) { //计算斐波那契 和更新进度一个异步函数 await Calc(i); i; } } //data i s public Task Calc(int data) { cts new CancellationTokenSource(); task new Task(s { //先取出计算第几位的斐波那契数 long num Convert.ToInt64(s); long result FiBo(num); try { Invoke(new Action(() { progressBar1.Value (int)num * 2; dataGridView1.Rows.Insert(0, new object[] { num, result });//添加行 num 第一列值,result 第二列值 if (stop) { i 0; progressBar1.Value 0; dataGridView1.Rows.Clear(); } })); } catch (Exception) { Console.WriteLine(); } //更新表格更新进度 },data,cts.Token); task.Start(); return task; } //封装斐波那契函数的功能 public long FiBo(long n) { if (n3) { return 1; } return FiBo(n - 1) FiBo(n - 2); } private void button2_Click(object sender, EventArgs e) { pause true; } private void button3_Click(object sender, EventArgs e) { pause false; button1_Click(null, null); } private void button4_Click(object sender, EventArgs e) { stop true; //cts.Cancel(); i 0; progressBar1.Value 0; dataGridView1.Rows.Clear(); } } }

相关新闻

主流嵌入式处理器架构深度解析:从ARM到RISC-V的演进与选型

主流嵌入式处理器架构深度解析:从ARM到RISC-V的演进与选型

1. 嵌入式处理器架构概述我第一次接触嵌入式处理器是在2013年,当时用一块STM32F103开发板做智能家居项目。那时候就被这种"麻雀虽小五脏俱全"的芯片震撼到了——指甲盖大小的芯片里竟然集成了CPU、内存、外设接口等完整计算机系统。经过这些年的发展&…

2026/7/15 5:33:14 阅读更多 →
【Kafka】Windows下Kafka 4.0 KRaft模式安装与初体验

【Kafka】Windows下Kafka 4.0 KRaft模式安装与初体验

1. Kafka 4.0 KRaft模式简介Kafka 4.0版本带来了一个重大变革——彻底抛弃了ZooKeeper依赖,转而采用全新的KRaft(Kafka Raft Metadata)共识协议。这个改变让Kafka的架构变得更加简洁高效。我最近在Windows上实测了这套新机制,发现…

2026/7/15 5:33:14 阅读更多 →
【关注可白嫖源码】--课程设计+毕业设计+springboot快递代拿系统[编号:project16522](案例分析)

【关注可白嫖源码】--课程设计+毕业设计+springboot快递代拿系统[编号:project16522](案例分析)

本文仅展示核心实现逻辑与部分代码片段,完整项目源码、配套文档、数据库脚本内容较多,篇幅有限无法全部放出。 有需要完整资源的同学,可以在评论区留言【资料或领源码】,我会一 一回复站内私信,发送完整文件 摘 要 随…

2026/7/15 5:31:13 阅读更多 →

最新新闻

洗车难题:大模型常识推理能力的压力测试标尺

洗车难题:大模型常识推理能力的压力测试标尺

1. 项目概述:一场关于“洗车难题”的真实压力测试你有没有试过,把一个看似简单的生活问题,扔给当前最热门的大模型,然后眼睁睁看着它在常识的浅滩上翻船?“洗车”就是这样一个经典案例——它不涉及高深数学&#xff0c…

2026/7/15 6:23:36 阅读更多 →
LM25141-Q1汽车电源环路补偿设计:从电流模式原理到工程实践

LM25141-Q1汽车电源环路补偿设计:从电流模式原理到工程实践

1. 项目概述与核心价值如果你正在设计一款汽车信息娱乐系统、高级驾驶辅助系统(ADAS)或者车载仪表盘的电源,并且对输入电压瞬态、低温启动以及严苛的电磁兼容性(EMI)要求感到头疼,那么LM25141-Q1这款器件很…

2026/7/15 6:21:35 阅读更多 →
FPGA入门(七):实现4路LED不同频率独立闪烁

FPGA入门(七):实现4路LED不同频率独立闪烁

FPGA入门 文章目录FPGA入门前言一、整体设计思路二、完整代码2.1 底层单路LED闪烁模块 led_twinkle.v2.2 顶层4路不同频率闪烁模块(led_twinkle_4.v)三、频率与参数的关系四、重点精讲:Verilog两种Parameter参数修改方式4.1 实例化 # 直接传参…

2026/7/15 6:21:35 阅读更多 →
Java二叉树遍历:从递归到迭代,用栈与队列的视角彻底讲透

Java二叉树遍历:从递归到迭代,用栈与队列的视角彻底讲透

1. 二叉树遍历的本质是什么?很多Java开发者第一次接触二叉树遍历时,往往会把注意力集中在代码实现上,却忽略了最核心的问题:我们为什么要用不同的方式遍历同一棵树?这就像用不同的路线逛同一个公园——前序遍历像从正门…

2026/7/15 6:21:35 阅读更多 →
51单片机定时器/计数器:从寄存器配置到精准时钟实战

51单片机定时器/计数器:从寄存器配置到精准时钟实战

1. 51单片机定时器/计数器基础概念第一次接触51单片机的定时器功能时,我盯着TCON、TMOD这些寄存器名称发呆了半小时。后来才明白,这就像给厨房电器定时——只不过我们现在是用代码来控制芯片内部的"电子钟表"。定时器和计数器本质上都是加法器…

2026/7/15 6:17:34 阅读更多 →
C++多线程性能优化实战:从锁竞争到无锁编程的高级技巧

C++多线程性能优化实战:从锁竞争到无锁编程的高级技巧

1. 项目概述:从“能用”到“好用”的C多线程进阶之路最近在社区里看到不少朋友在讨论C多线程编程,尤其是当项目从单线程转向多线程,或者并发量上来之后,各种性能瓶颈和诡异的Bug就冒出来了。我自己在游戏服务器和高频交易系统里摸…

2026/7/15 6:17:34 阅读更多 →

日新闻

YOLO11 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

YOLO11 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

前言 本文介绍了面向红外小目标检测的时空特征融合模块——STFFM,用于增强复杂背景下目标与噪声、杂波的区分能力。该方法通过拼接空间特征与时间/运动特征,并结合通道注意力、空间注意力和残差增强机制,实现对关键语义通道与疑似目标区域的…

2026/7/15 0:01:00 阅读更多 →
YOLO26 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

YOLO26 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

前言 本文介绍了面向复杂背景小目标检测的时空特征融合模块——STFFM。该模块通过空间分支与时间/运动分支的特征拼接,引入通道注意力和空间注意力对融合特征进行自适应筛选,并结合残差增强与通道压缩,突出目标区域、抑制背景噪声。我们将 S…

2026/7/15 0:01:00 阅读更多 →
行星减速机为什么能提高扭矩?从功率守恒到输出扭矩校核

行星减速机为什么能提高扭矩?从功率守恒到输出扭矩校核

一、为什么减速以后扭矩会增大 旋转机械的功率、转速和扭矩之间存在以下关系: T 9550 P n 其中: T为扭矩,单位Nm; P为功率,单位kW; n为转速,单位r/min。 在功率基本不变的情况下:…

2026/7/15 0:03:00 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/14 16:53:23 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/14 14:00:13 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/14 7:15:24 阅读更多 →

月新闻