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 …...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
《Offer来了:Java面试核心知识点精讲》大纲
文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...
HTTPS证书一年多少钱?
HTTPS证书作为保障网站数据传输安全的重要工具,成为众多网站运营者的必备选择。然而,面对市场上种类繁多的HTTPS证书,其一年费用究竟是多少,又受哪些因素影响呢? 首先,HTTPS证书通常在PinTrust这样的专业平…...
Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...
Python的__call__ 方法
在 Python 中,__call__ 是一个特殊的魔术方法(magic method),它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时(例如 obj()),Python 会自动调用该对象的 __call__ 方法…...
