很多时候,我们需要在窗体中执行一些耗时比较久的任务。比如:循环处理某些文件,发送某些消息等。。。

单纯的依靠状态栏,用户体验不佳,按下功能按钮后得不到有效的提醒,小白用户绝对会电话给你说“我点了以后就没反应了...”。

因此,对于响应时间可能超过5秒以上的事件,有必要增加一个显眼的提示框(在屏幕中央,最好有动图,如果有需要的话还可以设置为模态)。

此实现大体分三部分(重点在于使用BGWK解决UI阻塞的问题):

1、设计好提醒页面(一个转圈圈的动图Image,一个状态文字Label,再加一个进度条):

如果不需要动图,则这个窗体无需编写代码。

2、显示这个窗体的代码,目前放在基类窗体中被子类窗体继承。

         #region 显示应用程序作业状态
/// <summary>
/// 后台作业线程定义模板类
/// </summary>
protected class BgwkDef
{
public BackgroundWorker TagBgwk;
public Action RunningAction;
public int TProgMinimum = ;
public int TProgStep = ;
public int TProgMaximum = ;
public string RunningStatus;
} /// <summary>
/// 以指定的定义开始一个线程运行作业任务
/// </summary>
/// <param name="sBgwkDef"></param>
protected void BeginBgwork(BgwkDef sBgwkDef)
{
if (frmStatus == null)
{
frmStatus = new FrmStatus();
}
if (frmStatus != null)
{
frmStatus.ProgMain.Minimum = sBgwkDef.TProgMinimum;
frmStatus.ProgMain.Step = sBgwkDef.TProgStep;
frmStatus.ProgMain.Maximum = sBgwkDef.TProgMaximum;
frmStatus.TopLevel = false;
frmStatus.Parent = this;
frmStatus.Show();
frmStatus.BringToFront();
frmStatus.Left = (this.Width - frmStatus.Width) / ;
frmStatus.Top = (this.Height - frmStatus.Height) / - ;
}
if (sBgwkDef.RunningAction == null)
{
MyMsg.Warning("系统后台任务必须指定作业方法,请检查!");
return;
} BackgroundWorker tagBgwk = sBgwkDef.TagBgwk ?? new BackgroundWorker();
tagBgwk.WorkerSupportsCancellation = true;
tagBgwk.WorkerReportsProgress = true;
tagBgwk.DoWork -= BgwkBase1_DoWork;
tagBgwk.DoWork += BgwkBase1_DoWork;
tagBgwk.ProgressChanged -= BgwkBase1_ProgressChanged;
tagBgwk.ProgressChanged += BgwkBase1_ProgressChanged;
tagBgwk.RunWorkerCompleted -= BgwkBase1_RunWorkerCompleted;
tagBgwk.RunWorkerCompleted += BgwkBase1_RunWorkerCompleted;
tagBgwk.RunWorkerAsync(sBgwkDef.RunningAction);
} /// <summary>
/// 取消后台任务的当前作业
/// </summary>
/// <param name="tagBgwk"></param>
protected void CancelBgwork(BackgroundWorker tagBgwk)
{
tagBgwk.CancelAsync();
} /// <summary>
/// 在此事件中调用工作方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void BgwkBase1_DoWork(object sender, DoWorkEventArgs e)
{
((Action)e.Argument).Invoke();
} /// <summary>
/// 当后台任务运行进行进度报告时在状态窗口中显示状态
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void BgwkBase1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (frmStatus != null)
{
frmStatus.ProgMain.Value = e.ProgressPercentage > frmStatus.ProgMain.Maximum ? frmStatus.ProgMain.Maximum : e.ProgressPercentage;
frmStatus.ProgMain.PerformStep();
frmStatus.LabMessage.Text = e.UserState.ToString();
frmStatus.LabMessage.Refresh();
}
SetMainStatus(e.UserState.ToString());
} /// <summary>
/// 任务结束后(e.ProgressPercentage到100)关闭状态窗口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void BgwkBase1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
}
if (frmStatus != null)
{
frmStatus.Close();
frmStatus = null;
}
}
#endregion

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(, "正在尝试导出到EXCEL...");
//打开Excel等操作
//各种操作......
if ("出错了")
{
CancelBgwork(bgwk);//取消任务
MyMsg.Exclamation("开启报表文件失败,请检查!");
return;
}
//继续运行......
//最后完成任务
bgwk.ReportProgress(, "导出成功!");
return;

这样,比较简单的就完成了一个友好提示功能。

最新文章

  1. Win10下Android studio配置
  2. fir.im Weekly - Mobile developer 利器分享
  3. Winfrom动态创建控件
  4. [转] MongoDB shell 操作 (查询)
  5. Xcode关闭ARC
  6. 《Pandoc用户指南》之一
  7. Nodejs实现web静态服务器对多媒体文件的支持
  8. Swift - 使用闭包筛选过滤数据元素
  9. Python爬虫从入门到放弃(二十二)之 爬虫与反爬虫大战
  10. 编写shell时,提示let/typeset:not found
  11. FJUT寒假第一周作业浮点数查寻题解
  12. mysql 的mgr集群
  13. Apache Commons 工具类简单使用
  14. Python第7天
  15. xbee3的先进性功能用法
  16. 多态(upcast)减少分支判断 以及 多态继承设计、具体类型判断。
  17. ebs 12.1.1 单节点多用户安装
  18. HDU 1385 Minimum Transport Cost (输出字典序最小路径)【最短路】
  19. SpringCloud实现集群和负载均衡
  20. Java – Stream has already been operated upon or closed

热门文章

  1. temp3
  2. 基于JNI,JAVA 调用 C++入门
  3. krpano之语音介绍
  4. shell cut 用法
  5. c语言实践 数字特征值
  6. Reddit指南
  7. 在Asp.Net中使用amChart统计图
  8. HTML中meta标签的作用与使用
  9. Flask解决跨域
  10. does not name a type