文章目录
- 前言
- 一、背景介绍
- 二、使用BackgroundWorker组件实现异步加载数据
-
- [2.1 添加BackgroundWorker组件](#2.1 添加BackgroundWorker组件)
- [2.2 处理DoWork事件](#2.2 处理DoWork事件)
- 三、延伸内容
-
- [3.1 错误处理和进度报告](#3.1 错误处理和进度报告)
- [3.2 线程安全](#3.2 线程安全)
- 结束语
- 优质源码分享
C# winfrom 异步加载数据不影响窗体UI
,在 WinForms 应用程序中,如果数据加载是一个比较耗时的操作(比如从数据库读取大量数据、加载大型文件等),直接在主线程中进行加载会导致 UI 冻结。这是因为 WinForms 的 UI 是单线程的,主线程被阻塞时就无法处理其他 UI 相关的任务,如用户输入、界面更新等。而异步加载数据可以解决这个问题,让数据加载在后台线程进行,UI 线程可以继续响应用户操作。
前言
在数字浪潮汹涌澎湃的时代,程序开发宛如一座神秘而宏伟的魔法城堡,矗立在科技的浩瀚星空中。代码的字符,似那闪烁的星辰,按照特定的轨迹与节奏,组合、交织、碰撞,即将开启一场奇妙且充满无限可能的创造之旅。当空白的文档界面如同深邃的宇宙等待探索,程序员们则化身无畏的星辰开拓者,指尖在键盘上轻舞,准备用智慧与逻辑编织出足以改变世界运行规则的程序画卷,在 0 和 1 的二进制世界里,镌刻下属于人类创新与突破的不朽印记。
一、背景介绍
在 WinForms 应用程序中,如果数据加载是一个比较耗时的操作(比如从数据库读取大量数据、加载大型文件等),直接在主线程中进行加载会导致 UI 冻结。这是因为 WinForms 的 UI 是单线程的,主线程被阻塞时就无法处理其他 UI 相关的任务,如用户输入、界面更新等。而异步加载数据可以解决这个问题,让数据加载在后台线程进行,UI 线程可以继续响应用户操作。
二、使用BackgroundWorker组件实现异步加载数据
2.1 添加BackgroundWorker组件
添加BackgroundWorker组件:在 WinForms 设计器中,从工具箱的 "组件" 选项卡中找到 "BackgroundWorker" 并将其拖放到窗体上。
2.2 处理DoWork事件
处理DoWork事件:这个事件在后台线程中执行,用于加载数据。例如,如果要从数据库加载数据,可以在这个事件处理程序中编写数据库访问代码。
csharp
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// 这里模拟一个耗时的数据加载操作,比如从数据库读取数据
System.Threading.Thread.Sleep(5000);
// 假设这里是真正从数据库获取数据的代码
List<string> data = new List<string>();
data.Add("Data 1");
data.Add("Data 2");
// 将加载的数据作为结果返回
e.Result = data;
}
处理RunWorkerCompleted事件:当后台操作完成后,这个事件会在主线程中被触发。在这里可以更新 UI 来显示加载的数据。
csharp
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
List<string> data = (List<string>)e.Result;
// 假设dataGridView1是一个DataGridView控件,用于显示数据
dataGridView1.DataSource = data;
}
else
{
// 处理错误情况,比如显示错误消息
MessageBox.Show("数据加载出错:" + e.Error.Message);
}
}
启动异步操作:可以在某个按钮的点击事件或者窗体的加载事件等地方启动BackgroundWorker。
csharp
private void button1_Click(object sender, EventArgs e)
{
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync();
}
}
使用async/await实现异步加载数据(如果数据加载操作本身支持异步方法)
假设你有一个异步方法来加载数据,例如从网络获取数据的异步方法。
csharp
private async void button2_Click(object sender, EventArgs e)
{
// 假设LoadDataAsync是一个异步方法,用于加载数据
List<string> data = await LoadDataAsync();
dataGridView1.DataSource = data;
}
这个LoadDataAsync方法可能内部使用HttpClient从网络获取数据等,并且使用async和await关键字来实现异步操作。例如:
csharp
private async Task<List<string>> LoadDataAsync()
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync("https://example.com/api/data");
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
// 假设这里是将JSON数据反序列化为List<string>的代码
return JsonConvert.Deserialize<List<string>>(json);
}
else
{
throw new Exception("数据加载失败");
}
}
}
三、延伸内容
3.1 错误处理和进度报告
错误处理和进度报告:在BackgroundWorker中,可以通过RunWorkerCompletedEventArgs.Error属性来处理错误,还可以使用BackgroundWorker.ProgressChanged事件来报告进度。对于async/await,可以使用try - catch块来处理异常,并且如果加载过程有进度信息,可以通过事件或者返回的进度对象来更新 UI 显示进度。
3.2 线程安全
线程安全:在更新 UI 时,要确保操作是线程安全的。对于BackgroundWorker,因为RunWorkerCompleted事件是在主线程中触发的,所以可以直接更新 UI。但如果是在其他异步场景下,可能需要使用Invoke或BeginInvoke方法来确保在主线程中更新 UI,以避免跨线程访问异常。
结束语
亲爱的朋友,无论前路如何漫长与崎岖,都请怀揣梦想的火种,因为在生活的广袤星空中,总有一颗属于你的璀璨星辰在熠熠生辉,静候你抵达。
愿你在这纷繁世间,能时常收获微小而确定的幸福,如春日微风轻拂面庞,所有的疲惫与烦恼都能被温柔以待,内心永远充盈着安宁与慰藉。
至此,文章已至尾声,而您的故事仍在续写,不知您对文中所叙有何独特见解?期待您在心中与我对话,开启思想的新交流。
--------------- 业精于勤,荒于嬉 ---------------
--------------- 行成于思,毁于随 ---------------
优质源码分享
💞 关注博主 带你实现畅游前后端
🏰 大屏可视化 带你体验酷炫大屏
💯 神秘个人简介 带你体验不一样得介绍
🎀 酷炫邀请函 带你体验高大上得邀请
① 🉑提供云服务部署(有自己的阿里云);
② 🉑提供前端、后端、应用程序、H5、小程序、公众号等相关业务;
如🈶合作请联系我,期待您的联系。
注 :本文撰写于CSDN平台 ,作者:xcLeigh (所有权归作者所有) ,https://blog.csdn.net/weixin_43151418,如果相关下载没有跳转,请查看这个地址,相关链接没有跳转,皆是抄袭本文,转载请备注本文原地址。
亲,码字不易,动动小手,欢迎 点赞 ➕ 收藏,如 🈶 问题请留言(评论),博主看见后一定及时给您答复,💌💌💌
原文地址:https://blog.csdn.net/weixin_43151418/article/details/140635640(防止抄袭,原文地址不可删除)