C# 在Winform设计一个耗时较久的任务在后台执行时的状态提示窗口
标签:== top name progress export nim for 技术 div
很多时候,我们需要在窗体中执行一些耗时比较久的任务。比如:循环处理某些文件,发送某些消息等。。。
单纯的依靠状态栏,用户体验不佳,按下功能按钮后得不到有效的提醒,小白用户绝对会电话给你说“我点了以后就没反应了...”。
因此,对于响应时间可能超过5秒以上的事件,有必要增加一个显眼的提示框(在屏幕中央,最好有动图,如果有需要的话还可以设置为模态)。
此实现大体分三部分(重点在于使用BGWK解决UI阻塞的问题):
1、设计好提醒页面(一个转圈圈的动图Image,一个状态文字Label,再加一个进度条):
如果不需要动图,则这个窗体无需编写代码。
2、显示这个窗体的代码,目前放在基类窗体中被子类窗体继承。
1 #region 显示应用程序作业状态
2 ///
3 /// 后台作业线程定义模板类
4 ///
5 protected class BgwkDef
6 {
7 public BackgroundWorker TagBgwk;
8 public Action RunningAction;
9 public int TProgMinimum = 0;
10 public int TProgStep = 1;
11 public int TProgMaximum = 100;
12 public string RunningStatus;
13 }
14
15 ///
16 /// 以指定的定义开始一个线程运行作业任务
17 ///
18 ///
19 protected void BeginBgwork(BgwkDef sBgwkDef)
20 {
21 if (frmStatus == null)
22 {
23 frmStatus = new FrmStatus();
24 }
25 if (frmStatus != null)
26 {
27 frmStatus.ProgMain.Minimum = sBgwkDef.TProgMinimum;
28 frmStatus.ProgMain.Step = sBgwkDef.TProgStep;
29 frmStatus.ProgMain.Maximum = sBgwkDef.TProgMaximum;
30 frmStatus.TopLevel = false;
31 frmStatus.Parent = this;
32 frmStatus.Show();
33 frmStatus.BringToFront();
34 frmStatus.Left = (this.Width - frmStatus.Width) / 2;
35 frmStatus.Top = (this.Height - frmStatus.Height) / 2 - 90;
36 }
37 if (sBgwkDef.RunningAction == null)
38 {
39 MyMsg.Warning("系统后台任务必须指定作业方法,请检查!");
40 return;
41 }
42
43 BackgroundWorker tagBgwk = sBgwkDef.TagBgwk ?? new BackgroundWorker();
44 tagBgwk.WorkerSupportsCancellation = true;
45 tagBgwk.WorkerReportsProgress = true;
46 tagBgwk.DoWork -= BgwkBase1_DoWork;
47 tagBgwk.DoWork += BgwkBase1_DoWork;
48 tagBgwk.ProgressChanged -= BgwkBase1_ProgressChanged;
49 tagBgwk.ProgressChanged += BgwkBase1_ProgressChanged;
50 tagBgwk.RunWorkerCompleted -= BgwkBase1_RunWorkerCompleted;
51 tagBgwk.RunWorkerCompleted += BgwkBase1_RunWorkerCompleted;
52 tagBgwk.RunWorkerAsync(sBgwkDef.RunningAction);
53 }
54
55 ///
56 /// 取消后台任务的当前作业
57 ///
58 ///
59 protected void CancelBgwork(BackgroundWorker tagBgwk)
60 {
61 tagBgwk.CancelAsync();
62 }
63
64 ///
65 /// 在此事件中调用工作方法
66 ///
67 ///
68 ///
69 protected void BgwkBase1_DoWork(object sender, DoWorkEventArgs e)
70 {
71 ((Action)e.Argument).Invoke();
72 }
73
74 ///
75 /// 当后台任务运行进行进度报告时在状态窗口中显示状态
76 ///
77 ///
78 ///
79 protected void BgwkBase1_ProgressChanged(object sender, ProgressChangedEventArgs e)
80 {
81 if (frmStatus != null)
82 {
83 frmStatus.ProgMain.Value = e.ProgressPercentage > frmStatus.ProgMain.Maximum ? frmStatus.ProgMain.Maximum : e.ProgressPercentage;
84 frmStatus.ProgMain.PerformStep();
85 frmStatus.LabMessage.Text = e.UserState.ToString();
86 frmStatus.LabMessage.Refresh();
87 }
88 SetMainStatus(e.UserState.ToString());
89 }
90
91 ///
92 /// 任务结束后(e.ProgressPercentage到100)关闭状态窗口
93 ///
94 ///
95 ///
96 protected void BgwkBase1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
97 {
98 if (e.Cancelled)
99 {
100 }
101 if (frmStatus != null)
102 {
103 frmStatus.Close();
104 frmStatus = null;
105 }
106 }
107 #endregion
View Code
3、调用第2步的显示方法的代码(实际工作场合)。
private void CmdExport_Click(object sender, EventArgs e)
{
//创建或匹配一个BackgroundWorker,初始化一个耗时任务
BackgroundWorker bgwk = new BackgroundWorker();
BgwkDef bgwkDef = new BgwkDef()
{
RunningAction = delegate () { ExportIvoice(bgwk); },
TagBgwk = bgwk
};
BeginBgwork(bgwkDef);
}
//耗时比较久的工作任务方法
private void ExportIvoice(BackgroundWorker bgwk)
{
bgwk.ReportProgress(1, "正在尝试导出到EXCEL...");
//打开Excel等操作
//各种操作......
if ("出错了")
{
CancelBgwork(bgwk);//取消任务
MyMsg.Exclamation("开启报表文件失败,请检查!");
return;
}
//继续运行......
//最后完成任务
bgwk.ReportProgress(100, "导出成功!");
return;
}
这样,比较简单的就完成了一个友好提示功能。
C# 在Winform设计一个耗时较久的任务在后台执行时的状态提示窗口
标签:== top name progress export nim for 技术 div
原文地址:https://www.cnblogs.com/imes/p/9732611.html
评论