当前位置: 首页 > news >正文

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. 使用 DispatcherInvoke

在 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)

注&#xff1a;下文摘自ChatGPT&#xff0c;总结与案例都非常完善&#xff0c;可以快速理解并应用 0&#xff1a;使用场景 在winform界面程序中&#xff0c;在ui操作中涉及到一些耗时的等待操作&#xff0c;使用线程自己处理已经显得力不从心&#xff0c;如何能更好的实现&am…...

TCP/IP学习笔记

TCP\IP从实际应用的五层结构开始&#xff0c;自顶而下的去分析每一层。 TCP/IP五层架构概述 学术上面是TCP/IP四层架构&#xff0c;OSI/ISO是七层架构&#xff0c;实际中使用的是TCP/IP五层架构。 数据链路层 ICMP数据包分析 Wireshark抓包分析ICMP协议_wireshark抓ping包分析…...

0000_vim自定义快捷键_alias

vim自定义快捷键_alias 如下&#xff1a; 1.直接打开vi ~/.bashrc 然后到最底部&#xff0c;添加alias快捷键 2.添加alias快捷键mgplat 以后只要发送mgplat就等于出发了那么长一条指令 3.保存退出即可 【注意】 操作完后&#xff0c;可能你用mgplat无法使用&#xff0c;可…...

Spring Boot项目中,实体类是否需要实现Serializable接口

在Spring Boot项目中&#xff0c;实体类是否需要实现Serializable接口并不是一个硬性规定&#xff0c;而是取决于具体的应用场景和需求。以下是对这一问题的更详细分析&#xff1a; 1. 序列化的基本概念 序列化是将对象的状态信息转换为可以存储或传输的形式的过程。反序列化则…...

打通工业通信壁垒实现Ethernetip转profinet网络互通

西门子S7-1500 PLC&#xff08;profinet&#xff09;与AB PLC 1769-L32E以太网通讯&#xff08;EtherNet/IP&#xff09;。今天与大家分享一篇Profinet转EtherNet/IP的通讯配置方案。本文主要介绍开疆智能的Profinet转EtherNet/IP网关KJ-PNG-208&#xff0c;连接西门子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&#xff1a;基于.NET Framework&#xff0c;使用XAML&#xff08;可扩展应用程序标记语言&#xff09;作为界面描述语言&#xff0c;支持矢量图形和高级布局。WinForms&#xff1a;基于.NET Framework&#xff0c;使用纯代码或拖放设计…...

快速理解微服务中Ribbon的概念

一.基本概念 1.在微服务架构中&#xff0c;Ribbon 是一个客户端负载均衡器&#xff0c;用于控制服务间的通信方式。 2.Ribbon 是一个开源的库&#xff0c;最早由 Netflix 开发&#xff0c;用于实现客户端负载均衡。 3.Ribbon 主要解决的是在微服务架构中&#xff0c;多个服务…...

K8S简介、使用教程

以下是关于 Kubernetes&#xff08;通常缩写为 K8S&#xff09;的简介和使用教程&#xff1a; 一、Kubernetes 简介 定义与作用 Kubernetes 是一个开源的容器编排平台&#xff0c;用于自动化部署、扩展和管理容器化应用程序。它最初由谷歌开发&#xff0c;后捐赠给云原生计算基…...

极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【四】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…...

麦肯锡报告 | 科技落地的真谛:超越技术本身的价值创造

科技创新正在以惊人的速度改变企业运作和客户体验&#xff0c;但实现其潜力的关键在于正确的策略、流程、文化和人才。麦肯锡强调了一个理念&#xff1a;Never just tech&#xff08;不仅仅是技术&#xff09;。这表明&#xff0c;成功的数字化转型不仅依赖于技术&#xff0c;还…...

彻底解决 macOS 下Matplotlib 中文显示乱码问题

彻底解决 macOS 下Matplotlib 中文显示乱码问题 在使用 Python 的 Matplotlib 库进行数据可视化时&#xff0c;中文字符的显示常常会出现乱码问题&#xff0c;尤其在 macOS 系统上。在网上找了一大堆方法&#xff0c;花了很久&#xff0c;发现不是要安装各种字体就是要改配置&…...

STM32-- keil 的option for target使用

keil版本号 1.device界面 如&#xff1a;stm32f103c8t6的工程&#xff0c;可以直接在device这里修改成stm32f103vct6&#xff0c;虽然引脚不一样&#xff0c;但是很多一样的地方&#xff0c;可以直接使用&#xff0c;有些不修改也可以下载程序。 2.target xtal的设置不起作用了…...

【MCU】微控制器的编程技术:ISP 与 IAP

在嵌入式领域中&#xff0c;将程序下载到内置 Flash 有两种技术 ISP (In-system programming) ISP 即在系统编程&#xff0c;是指一些可编程逻辑器件、微控制器、芯片组和其他嵌入式设备在安装到完整嵌入式系统后能够进行编程&#xff0c;而不需要在将芯片安装到系统中之前对…...

C#基础题总结

16.一张单据上有一个5位数的号码为6**42&#xff0c;其中百位数和千位数已模糊不清&#xff0c;但知道该数能被 57 和 67 除尽。设计一个算法&#xff0c;找出该单据所有可能的号码。 17.编程序求2&#xff5e;10000以内的完全数。一个数的因子&#xff08;除了这个数本身&…...

Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?

大家好&#xff0c;我是锋哥。今天分享关于【Elasticsearch中的节点&#xff08;比如共20个&#xff09;&#xff0c;其中的10个选了一个master&#xff0c;另外10个选了另一个master&#xff0c;怎么办&#xff1f;】面试题。希望对大家有帮助&#xff1b; Elasticsearch中的节…...

《参与中型项目,领略 Spring 魅力》

一、Spring 在中型项目中的魅力展现 Spring 框架以其强大的功能和灵活性&#xff0c;在中型项目中发挥着重要作用。它不仅简化了开发过程&#xff0c;还提高了代码的可维护性和可扩展性。 Spring 在中型项目中魅力十足&#xff0c;其优势主要体现在以下几个方面。 首先&#…...

计算机网络-GRE(通用路由封装协议)简介

昨天我们学习了VPN的基本概念&#xff0c;虚拟专用网络在当前企业总部与分支间广泛使用。常用的划分方法为基于协议层次有GRE VPN、IPSec VPN、L2TP VPN、PPTP VPN、SSL VPN等。其实我有考虑该怎么讲&#xff0c;因为在IP阶段好像虚拟专用网络讲得不深&#xff0c;在IE的阶段会…...

开源电话机器人产品的优点是什么?

开源电话机器人产品的优点是什么&#xff1f; 作者&#xff1a;开源呼叫中心系统 FreeIPCC&#xff0c;Github地址&#xff1a;https://github.com/lihaiya/freeipcc 开源电话机器人产品作为人工智能技术的一种应用&#xff0c;近年来在电销、客户服务等多个领域展现出了显著的…...

Spring Boot 集成 Knife4j 的 Swagger 文档

在开发微服务应用时&#xff0c;API 文档的生成和维护是非常重要的一环。Swagger 是一个非常流行的 API 文档工具&#xff0c;可以帮助我们自动生成 RESTful API 的文档&#xff0c;并提供了一个友好的界面供开发者测试 API。本文将介绍如何在 Spring Boot 项目中集成 Knife4j …...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...