c#异步编程(async/await)
注:下文摘自ChatGPT,总结与案例都非常完善,可以快速理解并应用
0:使用场景
在winform界面程序中,在ui操作中涉及到一些耗时的等待操作,使用线程自己处理已经显得力不从心,如何能更好的实现:能等待后台线程执行完,而且不阻塞UI。c#提供如下操作,高效满足此类应用场景,c++中同样有类似的用法(类似于QT线程间通信(信号槽))
1. 使用异步编程(async/await)
最推荐的解决方法是使用 async/await,它可以将耗时操作放到后台线程运行,同时保持 UI 线程的响应。
示例:
场景:按钮点击后等待一个耗时任务完成,但界面仍可响应。
private async void Button_Click(object sender, EventArgs e)
{// 显示加载状态Button.Enabled = false;Label.Text = "Processing...";// 执行耗时操作await Task.Run(() => LongRunningTask());// 恢复 UILabel.Text = "Done!";Button.Enabled = true;
}// 模拟一个耗时任务
private void LongRunningTask()
{Thread.Sleep(5000); // 模拟耗时操作,实际中可替换为真实逻辑
}
原理:
Task.Run将耗时操作放到线程池中运行,不阻塞主线程。await确保任务完成后才继续执行,但不阻塞 UI 线程。
2. 使用 BackgroundWorker
BackgroundWorker 是较老的异步模式,但仍可用于一些简单场景。
示例:
private BackgroundWorker worker;public MainForm()
{InitializeComponent();worker = new BackgroundWorker();worker.DoWork += Worker_DoWork;worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
}private void Button_Click(object sender, EventArgs e)
{// 显示加载状态Button.Enabled = false;Label.Text = "Processing...";// 启动后台任务worker.RunWorkerAsync();
}private void Worker_DoWork(object sender, DoWorkEventArgs e)
{// 在后台线程中执行耗时操作Thread.Sleep(5000); // 模拟耗时操作
}private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{// 任务完成后更新 UILabel.Text = "Done!";Button.Enabled = true;
}
注意:
DoWork方法在后台线程中运行。RunWorkerCompleted方法在主线程(UI 线程)中运行,适合更新界面。
3. 使用 Task 和 Lambda
如果你不想使用 async/await,可以直接使用 Task 和回调来处理任务。
示例:
private void Button_Click(object sender, EventArgs e)
{// 显示加载状态Button.Enabled = false;Label.Text = "Processing...";Task.Run(() =>{// 在后台线程中执行耗时操作Thread.Sleep(5000); // 模拟耗时操作}).ContinueWith(t =>{// 回到主线程更新 UILabel.Text = "Done!";Button.Enabled = true;}, TaskScheduler.FromCurrentSynchronizationContext());
}
4. 使用 Dispatcher 或 Invoke
在 WPF 中,可以使用 Dispatcher 更新 UI;在 WinForms 中,可以使用 Invoke 方法。
示例(WinForms):
private void Button_Click(object sender, EventArgs e)
{Task.Run(() =>{// 耗时操作Thread.Sleep(5000);// 使用 Invoke 更新 UIthis.Invoke((Action)(() =>{Label.Text = "Done!";Button.Enabled = true;}));});// 立即禁用按钮(UI 线程)Button.Enabled = false;Label.Text = "Processing...";
}
5. 使用 Progress<T>(可选,报告进度)
如果耗时任务需要报告进度,可以使用 IProgress<T> 和 Progress<T>。
示例:
private async void Button_Click(object sender, EventArgs e)
{var progress = new Progress<int>(value =>{// 更新进度条ProgressBar.Value = value;});// 显示加载状态Button.Enabled = false;Label.Text = "Processing...";// 执行耗时任务并报告进度await Task.Run(() => LongRunningTaskWithProgress(progress));// 恢复 UILabel.Text = "Done!";Button.Enabled = true;
}private void LongRunningTaskWithProgress(IProgress<int> progress)
{for (int i = 0; i <= 100; i += 10){Thread.Sleep(500); // 模拟任务progress.Report(i); // 报告进度}
}
优点:
- 允许在任务进行过程中更新 UI(如进度条)。
6. 注意事项
- 避免直接使用
Thread.Sleep在主线程中运行:会导致 UI 完全无响应。 - 耗时操作不要在 UI 线程中运行:始终将耗时逻辑放到后台线程。
- 推荐使用现代的
async/await:代码更简洁且易于维护。
相关文章:
c#异步编程(async/await)
注:下文摘自ChatGPT,总结与案例都非常完善,可以快速理解并应用 0:使用场景 在winform界面程序中,在ui操作中涉及到一些耗时的等待操作,使用线程自己处理已经显得力不从心,如何能更好的实现&am…...
TCP/IP学习笔记
TCP\IP从实际应用的五层结构开始,自顶而下的去分析每一层。 TCP/IP五层架构概述 学术上面是TCP/IP四层架构,OSI/ISO是七层架构,实际中使用的是TCP/IP五层架构。 数据链路层 ICMP数据包分析 Wireshark抓包分析ICMP协议_wireshark抓ping包分析…...
0000_vim自定义快捷键_alias
vim自定义快捷键_alias 如下: 1.直接打开vi ~/.bashrc 然后到最底部,添加alias快捷键 2.添加alias快捷键mgplat 以后只要发送mgplat就等于出发了那么长一条指令 3.保存退出即可 【注意】 操作完后,可能你用mgplat无法使用,可…...
Spring Boot项目中,实体类是否需要实现Serializable接口
在Spring Boot项目中,实体类是否需要实现Serializable接口并不是一个硬性规定,而是取决于具体的应用场景和需求。以下是对这一问题的更详细分析: 1. 序列化的基本概念 序列化是将对象的状态信息转换为可以存储或传输的形式的过程。反序列化则…...
打通工业通信壁垒实现Ethernetip转profinet网络互通
西门子S7-1500 PLC(profinet)与AB PLC 1769-L32E以太网通讯(EtherNet/IP)。今天与大家分享一篇Profinet转EtherNet/IP的通讯配置方案。本文主要介绍开疆智能的Profinet转EtherNet/IP网关KJ-PNG-208,连接西门子S7-1500 …...
数据结构_图的应用
最小生成树 Prim算法 int AMGraph::sum(string v) {int start, totalW, cnt, minW, u, vv, i, j;start LocateVex(v); // 获取起始顶点编号memset(visited, false, sizeof(visited)); // 初始化访问状态visited[start] true;totalW 0; // 最小生成树的总权重cnt 1; // 当前…...
C#中面试的常见问题002
1.wpf和Winfrom的区别 1. 技术基础 WPF:基于.NET Framework,使用XAML(可扩展应用程序标记语言)作为界面描述语言,支持矢量图形和高级布局。WinForms:基于.NET Framework,使用纯代码或拖放设计…...
快速理解微服务中Ribbon的概念
一.基本概念 1.在微服务架构中,Ribbon 是一个客户端负载均衡器,用于控制服务间的通信方式。 2.Ribbon 是一个开源的库,最早由 Netflix 开发,用于实现客户端负载均衡。 3.Ribbon 主要解决的是在微服务架构中,多个服务…...
K8S简介、使用教程
以下是关于 Kubernetes(通常缩写为 K8S)的简介和使用教程: 一、Kubernetes 简介 定义与作用 Kubernetes 是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它最初由谷歌开发,后捐赠给云原生计算基…...
极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【四】
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料: 极狐GitLab 官网极狐…...
麦肯锡报告 | 科技落地的真谛:超越技术本身的价值创造
科技创新正在以惊人的速度改变企业运作和客户体验,但实现其潜力的关键在于正确的策略、流程、文化和人才。麦肯锡强调了一个理念:Never just tech(不仅仅是技术)。这表明,成功的数字化转型不仅依赖于技术,还…...
彻底解决 macOS 下Matplotlib 中文显示乱码问题
彻底解决 macOS 下Matplotlib 中文显示乱码问题 在使用 Python 的 Matplotlib 库进行数据可视化时,中文字符的显示常常会出现乱码问题,尤其在 macOS 系统上。在网上找了一大堆方法,花了很久,发现不是要安装各种字体就是要改配置&…...
STM32-- keil 的option for target使用
keil版本号 1.device界面 如:stm32f103c8t6的工程,可以直接在device这里修改成stm32f103vct6,虽然引脚不一样,但是很多一样的地方,可以直接使用,有些不修改也可以下载程序。 2.target xtal的设置不起作用了…...
【MCU】微控制器的编程技术:ISP 与 IAP
在嵌入式领域中,将程序下载到内置 Flash 有两种技术 ISP (In-system programming) ISP 即在系统编程,是指一些可编程逻辑器件、微控制器、芯片组和其他嵌入式设备在安装到完整嵌入式系统后能够进行编程,而不需要在将芯片安装到系统中之前对…...
C#基础题总结
16.一张单据上有一个5位数的号码为6**42,其中百位数和千位数已模糊不清,但知道该数能被 57 和 67 除尽。设计一个算法,找出该单据所有可能的号码。 17.编程序求2~10000以内的完全数。一个数的因子(除了这个数本身&…...
Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?
大家好,我是锋哥。今天分享关于【Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?】面试题。希望对大家有帮助; Elasticsearch中的节…...
《参与中型项目,领略 Spring 魅力》
一、Spring 在中型项目中的魅力展现 Spring 框架以其强大的功能和灵活性,在中型项目中发挥着重要作用。它不仅简化了开发过程,还提高了代码的可维护性和可扩展性。 Spring 在中型项目中魅力十足,其优势主要体现在以下几个方面。 首先&#…...
计算机网络-GRE(通用路由封装协议)简介
昨天我们学习了VPN的基本概念,虚拟专用网络在当前企业总部与分支间广泛使用。常用的划分方法为基于协议层次有GRE VPN、IPSec VPN、L2TP VPN、PPTP VPN、SSL VPN等。其实我有考虑该怎么讲,因为在IP阶段好像虚拟专用网络讲得不深,在IE的阶段会…...
开源电话机器人产品的优点是什么?
开源电话机器人产品的优点是什么? 作者:开源呼叫中心系统 FreeIPCC,Github地址:https://github.com/lihaiya/freeipcc 开源电话机器人产品作为人工智能技术的一种应用,近年来在电销、客户服务等多个领域展现出了显著的…...
Spring Boot 集成 Knife4j 的 Swagger 文档
在开发微服务应用时,API 文档的生成和维护是非常重要的一环。Swagger 是一个非常流行的 API 文档工具,可以帮助我们自动生成 RESTful API 的文档,并提供了一个友好的界面供开发者测试 API。本文将介绍如何在 Spring Boot 项目中集成 Knife4j …...
告别模糊地图!5分钟教你用leafletwx实现微信小程序高清地图渲染
5分钟实战:用leafletwx为微信小程序打造视网膜级高清地图 第一次在小程序里集成地图时,我盯着屏幕上模糊的路线和文字皱起了眉头——原生map组件在高端手机上的表现简直像回到了像素游戏时代。直到发现leafletwx这个开源神器,才明白原来微信小…...
RWKV7-1.5B-g1a轻量对话模型应用:微信公众号自动回复+知识库问答搭建
RWKV7-1.5B-g1a轻量对话模型应用:微信公众号自动回复知识库问答搭建 1. 模型简介与特点 rwkv7-1.5B-g1a 是基于 RWKV-7 架构的多语言文本生成模型,特别适合中文轻量对话场景。相比传统大模型,它具有以下优势: 资源占用低&#…...
保姆级教程:在Windows 11上用VSCode和Conda搞定Depth-Anything-3(含常见报错修复)
Windows 11深度估计实战:VSCodeConda环境下的Depth-Anything-3全流程指南 深度估计作为计算机视觉领域的重要技术,正在自动驾驶、增强现实等场景中发挥关键作用。本文将带你在Windows 11系统上,使用VSCode和Conda搭建Depth-Anything-3开发环境…...
OpCore-Simplify:实现OpenCore EFI自动化生成的黑苹果配置解决方案
OpCore-Simplify:实现OpenCore EFI自动化生成的黑苹果配置解决方案 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 副标题:告别…...
我花了 3 小时吃透:Spring AI 核心三剑客 ChatModel、Prompt、ChatResponse 到底怎么用?
你在学习 Spring AI 的时候,肯定遇到过这三个类:ChatModel、Prompt、ChatResponse看着眼熟,却总搞不清谁负责干嘛、代码里为啥要这么写?接下来就是我的理解。一、先搞懂:这三个东西是什么关系?在开始写代码…...
Pixel Dimension Fissioner 与3D渲染结合:生成像素风格贴图与法线贴图
Pixel Dimension Fissioner 与3D渲染结合:生成像素风格贴图与法线贴图 1. 效果亮点预览 Pixel Dimension Fissioner在3D图形管线中展现出令人惊喜的适配性。这个工具最吸引人的地方在于,它能将传统像素艺术与现代3D渲染技术无缝结合,创造出…...
SGP30传感器数据不准?可能是你的I2C时序和初始化搞错了(避坑指南)
SGP30传感器数据异常排查指南:从硬件设计到软件调试的完整解决方案 1. 硬件设计中的常见陷阱与优化方案 SGP30作为一款高精度环境传感器,其硬件设计细节直接影响数据可靠性。许多开发者遇到的首要问题往往源于电路设计阶段被忽视的关键参数。 电源稳定性…...
Scarab:空洞骑士模组管理效率提升83%的智能工具
Scarab:空洞骑士模组管理效率提升83%的智能工具 【免费下载链接】Scarab An installer for Hollow Knight mods written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 如何解决模组管理难题?3大创新让你告别手动配置烦恼 对…...
2003-2024年上市公司政府补助数据+stata代码
政府补助数据2003-2024 范围:2003 - 2024年,全部A股上市公司 原始数据来源于国泰安,有计算代码和原始数据,可复现出计算结果 政府补贴,政府补助,政府津贴,2024数据全 计算结果:d…...
bert-base-chinese场景解析:从语义相似度计算到特征提取实战
BERT-base-chinese场景解析:从语义相似度计算到特征提取实战 1. 模型概述与核心价值 BERT-base-chinese是Google推出的中文预训练语言模型,基于Transformer架构构建,专门针对中文文本处理进行了优化。作为NLP领域的里程碑式模型,…...
