文档章节

.net开发笔记(十八) winform中的等待框

IT周见智
 IT周见智
发布于 2015/06/05 17:17
字数 1156
阅读 13
收藏 0
点赞 0
评论 0

      winform中很多任务是需要在后台线程(或类似)中完成的,也就是说,经常容易涉及到UI界面与后台工作线程之间的交互。比如UI界面控制后台工作的执行(启动、暂停、停止等),后台工作进度在UI界面上的显示。前两天一个员工在UI线程中访问数据库,刚开始数据库在局域网中,没感觉到什么,后来将数据库移到了外网,发现问题来了,至于问题原因想必诸位都知晓,更详细的解释请参考本系列博客(四)。后将这方面的东西整理了一下,如下:

执行后台任务时,UI界面应该怎么做?大概分两种情况:(我自己随便给取的名字)

(1)一种是模式等待

也就说,后台工作没有完成之前,UI界面不允许操作,如下图:

图1

如上图所示,红色箭头表示后台跟UI界面的交互。

(2)一种是非模式等待

后台工作没完成之前,UI界面可以操作,这个类似文件拷贝出现的信息框,如下图:

图2

如上图所示,红色箭头表示后台与UI界面的交互。

以上是两种情况,以及对应的结构图,我做了一个Demo,包含两种等待窗体,一种即为“模式等待窗体”,另一种为“非模式等待窗体”。源码在文章结束后有下载地址。先来分别看一下两者的代码:

(1)模式等待窗体

 1 public partial class frmWait : Form
 2     {
 3         bool _run = true;
 4         public frmWait()
 5         {
 6             InitializeComponent();
 7         }
 8         public object DoWait(object param)
 9         {
10             List<string> list = new List<string>();
11             int count = (int)param;
12             progressBar1.Maximum = count;
13 
14             //---------------------以下代码片段可以使用线程代替
15             ((Action)delegate()
16             {
17                 System.Threading.Thread.Sleep(1000);
18 
19                     for (int i = 0; i < count; ++i) //耗时操作
20                     {
21                         if (_run)
22                         {
23                             string s = DateTime.Now.ToLongTimeString();
24                             list.Add(s);
25                             this.Invoke((Action)delegate()
26                             {
27                                 if (!IsDisposed)
28                                 {
29                                     progressBar1.Value = i;
30                                     label1.Text = "正在载入字符串 \"" + s + "\"";
31                                 }
32                             });
33                             System.Threading.Thread.Sleep(500);
34                         }
35                         else
36                         {
37                             break;
38                         }
39                     }
40 
41             }).BeginInvoke(new AsyncCallback(OnAsync), null);  //异步执行后台工作
42             //------------------------
43 
44             ShowDialog(); //UI界面等待
45             return list; //后台工作执行完毕 可以使用结果
46         }
47         private void OnAsync(IAsyncResult ar)
48         {
49             if (_run) //后台工作正常结束
50                 DialogResult = DialogResult.OK;
51         }
52         private void frmWait_Load(object sender, EventArgs e)
53         {
54 
55         }
56 
57         private void button1_Click(object sender, EventArgs e)
58         {
59             _run = false; //UI界面控制后台结束
60             DialogResult = DialogResult.Cancel;
61         }
62 }
View Code

如上代码所示,后台任务很简单,就是返回指定数目(param)个字符串,存放在一个list中,使用frmWait也很简单:

1  using (frmWait frmw = new frmWait())
2             {
3                 List<string> list = frmw.DoWait(50) as List<string>; //弹出模式等待窗体 实时更新显示后台工作进度 后台工作结束后  等待窗体消失  UI线程继续执行...
4                 MessageBox.Show("加载字符串 " + list.Count + "");
5             }
View Code

(2)非模式等待窗体

 1  public partial class frmNoWait : Form
 2     {
 3         bool _run = true;
 4         public frmNoWait()
 5         {
 6             InitializeComponent();
 7         }
 8         private void OnAsync(IAsyncResult ar)
 9         {
10             // ar.AsyncState as List<string> 后台工作执行完毕的结果
11 
12             if (_run) //后台工作正常结束
13                 this.Invoke((Action)delegate()
14                 {
15                     Close();
16                 });
17         }
18         public void DoNoWait(int param)
19         {
20             List<string> list = new List<string>();
21             int count = (int)param;
22             progressBar1.Maximum = count;
23 
24             //-----------------------以下代码片段 可以使用线程代替
25             ((Action)delegate()
26             {
27                 try
28                 {
29                     System.Threading.Thread.Sleep(1000);
30                     for (int i = 0; i < count; ++i) //耗时操作
31                     {
32                         if (_run)
33                         {
34                             string s = DateTime.Now.ToLongTimeString();
35                             list.Add(s);
36                             this.Invoke((Action)delegate()
37                             {
38                                 if (!IsDisposed)
39                                 {
40                                     progressBar1.Value = i;
41                                     label1.Text = "正在载入字符串 \"" + s + "\"";
42                                 }
43                             });
44                             System.Threading.Thread.Sleep(500);
45                         }
46                         else
47                         {
48                             break;
49                         }
50                     }
51                 }
52                 catch
53                 {
54 
55                 }
56             }).BeginInvoke(new AsyncCallback(OnAsync), list); //异步执行后台工作
57             //----------------------------
58 
59             Show();//UI界面不用等待
60         }
61         private void frmNoWait_Load(object sender, EventArgs e)
62         {
63             Text += (" " + Form1.index++ + "");
64         }
65 
66         private void button1_Click(object sender, EventArgs e)
67         {
68             Close();
69         }
70         protected override void OnFormClosing(FormClosingEventArgs e)
71         {
72             base.OnFormClosing(e);
73             _run = false; //UI界面控制后台结束
74         }
75     }
View Code

如上代码所示,后台工作开始后,弹出一个非模式对话框,UI界面可以继续操作,也就是说,你可以出现多个frmNoWait窗体,使用很简单,如下:

1 frmNoWait frmnw = new frmNoWait();
2 frmnw.DoNoWait(50);   //弹出窗体
3 //UI界面继续...
View Code

至于怎么通知UI界面,后台工作结束了,你可以在OnAsync中完成这个功能。

最后上几张截图:

图3

图4

源码下载地址:http://files.cnblogs.com/xiaozhi_5638/ProgressForm.rar

希望有帮助!

© 著作权归作者所有

共有 人打赏支持
IT周见智

IT周见智

粉丝 10
博文 61
码字总数 185891
作品 0
西青
我的友情链接

51CTO博客开发 吴光科-京峰Linux运维培训 上山路十八弯 pc的个人博客 不安分与好奇心 Linux运维之路启示录 抚琴煮酒 MJ为的笔记和总结 毛毛鸭 chinanet 煮酒品茶 柠檬 Linux运维重难点学习笔...

运维猫
2017/11/22
0
0
关于安卓应用迁移至Windows 8应用概览

开源力量公开课第二十八期-安卓应用迁移至Windows应用概览 2013年08月27日 ⁄ 公开课 ⁄ 评论关闭

刘华1314520
2013/08/21
143
0
如何在MyBatis-3.2.7中使用Log4j2 rc2——MyBatis学习笔记之十九

前天我上传了我的MyBatis系列课程(http://edu.51cto.com/course/course_id-1110.html)的第六讲,主要内容是如何使用Log4j2(具体版本为v2.0-rc1)为MyBatis 3.2.7配置日志。实际上目前最新...

NashMaster2011
2014/07/09
0
0
在DevExpress程序中使用SplashScreenManager控件实现启动闪屏和等待信息窗口

在我很早的WInform随笔《WinForm界面开发之"SplashScreen控件"》有介绍如何使用闪屏的处理操作,不过那种是普通WInform和DevExpress都适用的方案,如果是基于DevExpress,那么可以使用更简便...

walb呀
2017/12/04
0
0
《鸡啄米VS2010/MFC编程入门》系列技术文章整理收藏

《鸡啄米VS2010/MFC编程入门》系列技术文章整理收藏 1VS2010/MFC编程入门之前言 http://www.lai18.com/content/410337.html 2VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架) ...

开元中国2015
2015/06/27
267
0
MyBatis学习笔记系列教程

【MyBatis学习笔记】系列之预备篇一:ant的下载与安装 【MyBatis学习笔记】系列之预备篇二:ant入门示例 【MyBatis学习笔记】系列之一:MyBatis入门示例 【MyBatis学习笔记】系列之二:MyBat...

HenrySun
2016/10/15
19
0
我的友情链接

51CTO博客开发 一步步踏入Linux世界 煮酒品茶 濛sir的积累 老男孩linux运维 龙哥 Smile 抚琴煮酒 大浪淘沙 温水煮青蛙 何秉昆De技术博客 浩子的▁运维笔录ヽ 见 linux---基础篇 个人随写 与I...

Anonymous123
2017/11/22
0
0
《Pro ASP.NET MVC 3 Framework》学习笔记目录

《Pro ASP.NET MVC 3 Framework》简介: 作者: Adam Freeman 和 Steven Sanderson 出版社: Apress; New 平装: 820页 语种: 英语 ISBN: 1430234040 声明:笔记里面按我自己的理解翻译了大部分...

mszhangxuefei
2012/02/07
0
0
RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2-新增锁定用户与解除锁定用户的功能

  锁定用户功能在现实应用场景中得到了大量的应用,当我们需要限制某用户的登录,又不能删除这个用户时就可以使用锁定功能,如:未授权的用户尝试错误密码错误过多可以尝试的用户进行锁定,...

80368704
06/29
0
0
Winform开发框架中工作流模块之审批会签操作(2)

前面随笔介绍了请假申请单和报销申请单两个不同的业务表单的流程处理,一个是单表信息,一个包含明细的主从表信息,后者包含了条件流程的处理,在流程审批中,一般还有一种流程处理就是会签的...

walb呀
2017/12/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring配置xml启动报错 Connot find 'beans'

1.我们先看一下spring的原始配置 <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSc......

江湖鱼大虾
9分钟前
0
0
与女儿谈商业模式 (4):戴尔的成功秘诀

分类:与女儿谈商业模式 | 标签: 戴尔 经济学 陈志武 2007-05-15 10:26阅读(7434)评论(36)   2007年5月《创富志》与“女儿谈商业模式”专栏 (之四)   戴尔的成功秘诀   陈志武   ...

祖冲之
19分钟前
0
0
www.w3.org被qiang导致logback报错:Connect reset

web项目部署到tomcat后,web项目中的logback不能运行,报错信息如下: Reported exception: ch.qos.logback.core.joran.spi.JoranException: I/O error occurred while parsing xml file......

浮躁的码农
33分钟前
0
0
JDeveloper中文乱码解决

全局设置字体; 全局设置环境编码; 项目设置编译器环境编码。

wffger
今天
2
0
MySQL主从介绍 , 准备工作,配置主,配置从, 测试主从同步

MySQL主从介绍 MySQL主从又叫做Replication、AB复制。简单讲就是A和B两台机器做主从后,在A上写数据,另外一台B也会跟着写数据,两者数据实时同步的 MySQL主从是基于binlog的,主上须开启bin...

TaoXu
今天
2
0
线性代数学习总结

亭子happy
今天
1
0
Java8:Lambda表达式增强版Comparator和排序

1、概述 在这篇教程里,我们将要去了解下即将到来的JDK 8(译注,现在JDK 8已经发布了)中的Lambda表达式——特别是怎样使用它来编写Comparator和对集合(Collection)进行排序。 这篇文章是...

孟飞阳
今天
0
0
从架构到组件,深挖istio如何连接、管理和保护微服务2.0?

近几年我一直从事于微服务系统的设计以及实现方面的工作,属于微服务架构一线实践者。之前做过一些单体系统的微服务改造,在微服务拆分、治理等方面都有一定的经验。 本人比较特殊一点的经历...

xiaomin0322
今天
1
0
基于vue的h5文件切片上传(获取文件md5,实现秒传、进度条实现)

template <button @click="file"></button><label ref="upload" style="position: relative;"> <input type="file" @change="selectFile" style="position: abs......

hkaikai
今天
2
0
Spring Boot 2.0 项目实现自同步AD域账号

在通过Spring Boot的自动化装配功能及JDK自带的LDAP模块,可通过如下几个简单步骤实现业务系统自动同步AD域账号功能。 1. Java自带ldap搜索域账号信息核心代码: try { LdapContext ctx...

B超
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部