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

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

因此,对于响应时间可能超过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;

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

C# 在Winform设计一个耗时较久的任务在后台执行时的状态提示窗口的更多相关文章

  1. winform设计一个登录界面和修改密码的界面-自动切换窗体(问题[已解] 望一起讨论)(技术改变世界-cnblog)

    http://www.cnblogs.com/IAmBetter/archive/2012/01/14/2322156.html winform设计一个登录界面和修改密码的界面-自动切换窗体(问题[已 ...

  2. C# Winform下一个热插拔的MIS/MRP/ERP框架13(窗体基类)

    作为一个ERP数据处理框架,大部分的开发场景都差不多. 理想中,对于通用数据处理,我的步骤如下: 1.为窗体指定数据来源(数据表/查询等): 2.拖入编辑控件,指定绑定字段: 3.结束. 为此,我设计 ...

  3. 设计一个较好的框架的难点之一--API兼容性的设计

    设计一个好的框架和设计一个好的软件一样,需要考虑的方面很多,比如扩展性.性能.用户体验.稳健性等等,视不同的场景,每个点都可能导致成败,但他们通常并不是老板们关心的,因为在大部分情况下,他们通常都没有 ...

  4. 如何在asp.net中使用多线程及队列,异步处理一个耗时的任务(原创)

    最近想在使用.net 的队列处理一些耗时的工作.经过考虑,需要先设计一个类,类中包含一个静态的队列.主要是写队列和读取队列. public class PaperCalculator { // 用于存 ...

  5. 浅谈DevExpress<二>:设计一个完整界面(1)

    昨天谈了界面的换肤问题,今天拿一个简单的界面来介绍一下怎么设计一个五脏俱全的界面,总体效果如下图(种类的图片随便找的^^):

  6. 如何一步一步用DDD设计一个电商网站(十三)—— 领域事件扩展

    阅读目录 前言 回顾 本地的一致性 领域事件发布出现异常 订阅者处理出现异常 结语 一.前言 上篇中我们初步运用了领域事件,其中还有一些问题我们没有解决,所以实现是不健壮的,下面先来回顾一下. 二.回 ...

  7. webview之如何设计一个优雅健壮的Android WebView?(下)(转)

    转载:https://iluhcm.com/2018/02/27/design-an-elegant-and-powerful-android-webview-part-two/ (这篇文章写得有点晚 ...

  8. 如何设计一个异步Web服务——任务调度

    接上一篇<如何设计一个异步Web服务——接口部分> Application已经将任务信息发到了Service服务器中,接下来,Service服务器改如何对自身的资源进行合理分配以满足App ...

  9. WPF 多线程 UI:设计一个异步加载 UI 的容器

    对于 WPF 程序,如果你有某一个 UI 控件非常复杂,很有可能会卡住主 UI,给用户软件很卡的感受.但如果此时能有一个加载动画,那么就不会感受到那么卡顿了.UI 的卡住不同于 IO 操作或者密集的 ...

随机推荐

  1. kettle init oracle jdbc

  2. 安卓Animation类与xml制作动画

    有时要对控件添加一点动画效果,在安卓中,动画效果也是一个类,也就是Animation类.把动画效果这个类弄好后,在与控件类关联到一起,就可以实现控件有一些动作特效这样的效果了.动画效果的定义,要在xm ...

  3. 【整理】Android中的gravity和layout_gravity区别

    [背景] 在Android中,想要设置个按钮的水平对齐,都累死了: [已解决]ADT中已设置TableLayout布局的情况下如何设置按钮居中对齐    所以现在有必要搞清楚,到底gravity和la ...

  4. js处理小数加减时精度失真

    最近公司业务有用js处理数据加减,但有时候会出现很多位小数:后来发现是js处理小数时精度失真:为了后边不在犯类似错误,笔者觉得有必要记录下处理方法,当然处理方法有很多种,这里笔者找了一种较为简洁的方法 ...

  5. [ShaderStaff] Sprite Outline外轮廓效果

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Unity5.3.8f1 Unity提供了2D Object Sprite对象,但是没有提供外轮廓Outline效果的支持 ...

  6. XML文件中“>”和“<”的转码

    在xml文件中,大于号“>”和小于号“<”是不能被直接识别的,需要经过转码才可以被识别,转码后的格式如下: < < 小于 > > 大于

  7. ubuntu&nbsp;12.04修改环境变量PAT…

    这里我只针对ubuntu 12.04进行了测试,由于不同的linux发行版本可能会有一些地方不一致,所以对于其他的linux发行版仅供参考. 1.直接在命令行里添加  我们先来看下下PATH的值 ec ...

  8. MAVEN学习总结1

    一.安装Maven插件 下载下来的maven插件如下图所示:,插件存放的路径是:E:/MavenProject/Maven2EclipsePlugin

  9. 170318 11:44:26 [ERROR] Can't start server: can't create PID file: No space left on device

    数据库挂了.打开远程,进了系统,service mysqld stop 失败.service mysqld start等了好大一会,提示Timeout error occurred trying to ...

  10. Chrome,firefox,ie等浏览器空格&nbsp;宽度不一样

    方案一:使用其他字符代替空格 使用(&nbsp:)空格浏览器之间,显示的不一样,对不齐等现象. 解决方案: 用半角空格&ensp:或者全角空格&emsp:就可以了,&e ...