从目前已经在项目中工作将近一个月来的情况来看,凡是费时的操作,基本上都要用到多线程的等待窗体、进度提示窗体等实时显示动态的进度信息。而如果直接在主线程的窗体上实时更新信息,就会造成更新太快或者太慢而出现的进程假死现象。为了缓解这些情况,本文就参考一些文章,把他们的智慧总结于此。希望对大家有所帮助。

一、多线程中创建等待窗体

  在winform程序开发中,计算机经常会执行一些比较耗时的任务,如大量数据的查询操作、较为复杂的业务处理等,这些任务往往需要耗时几秒到几十秒钟的时间,在这些任务执行期间winform程序窗体不再响应任何鼠标和键盘事件,出现假死状态,用户体验很差。

  一个比较好的解决办法是,在这些任务执行期间在界面前端显示一个等待窗体,告诉用户任务正在执行中。

1.1 开发等待窗体

窗体中有一个PictureBox控件和两个Lable控件,PictureBox控件的Image属性为一张动态图片。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using System.Threading;
  9. using NavManager.Common;
  10.  
  11. namespace NavManager.Utils
  12. {
  13. public partial class WaitForm : Form
  14. {
  15. public WaitForm()
  16. {
  17. InitializeComponent();
  18. SetText("");
  19. }
  20.  
  21. private delegate void SetTextHandler(string text);
  22. public void SetText(string text)
  23. {
  24. if (this.label2.InvokeRequired)
  25. {
  26. this.Invoke(new SetTextHandler(SetText), text);
  27. }
  28. else
  29. {
  30. this.label2.Text = text;
  31. }
  32. }
  33. }
  34. }

等待窗体源码

1.2 提供访问等待窗体的接口

编写类WaitFormService

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading;
  5. using System.Windows.Forms;
  6.  
  7. namespace NavManager.Utils
  8. {
  9. /// <summary>
  10. /// Using Singleton Design Pattern
  11. /// </summary>
  12. public class WaitFormService
  13. {
  14. public static void CreateWaitForm()
  15. {
  16. WaitFormService.Instance.CreateForm();
  17. }
  18.  
  19. public static void CloseWaitForm()
  20. {
  21. WaitFormService.Instance.CloseForm();
  22. }
  23.  
  24. public static void SetWaitFormCaption(string text)
  25. {
  26. WaitFormService.Instance.SetFormCaption(text);
  27. }
  28.  
  29. private static WaitFormService _instance;
  30. private static readonly Object syncLock = new Object();
  31.  
  32. public static WaitFormService Instance
  33. {
  34. get
  35. {
  36. if (WaitFormService._instance == null)
  37. {
  38. lock (syncLock)
  39. {
  40. if (WaitFormService._instance == null)
  41. {
  42. WaitFormService._instance = new WaitFormService();
  43. }
  44. }
  45. }
  46. return WaitFormService._instance;
  47. }
  48. }
  49.  
  50. private WaitFormService()
  51. {
  52. }
  53.  
  54. private Thread waitThread;
  55. private WaitForm waitForm;
  56.  
  57. public void CreateForm()
  58. {
  59. if (waitThread != null)
  60. {
  61. try
  62. {
  63. waitThread.Abort();
  64. }
  65. catch (Exception)
  66. {
  67. }
  68. }
  69.  
  70. waitThread = new Thread(new ThreadStart(delegate()
  71. {
  72. waitForm = new WaitForm();
  73. Application.Run(waitForm);
  74. }));
  75. waitThread.Start();
  76. }
  77.  
  78. public void CloseForm()
  79. {
  80. if (waitThread != null)
  81. {
  82. try
  83. {
  84. waitThread.Abort();
  85. }
  86. catch (Exception)
  87. {
  88. }
  89. }
  90. }
  91.  
  92. public void SetFormCaption(string text)
  93. {
  94. if (waitForm != null)
  95. {
  96. try
  97. {
  98. waitForm.SetText(text);
  99. }
  100. catch (Exception)
  101. {
  102. }
  103. }
  104. }
  105.  
  106. }
  107. }

WaitFormService Class Code

1.3 使用WaitFormService提供的接口

  1. try
  2. {
  3. WaitFormService.CreateWaitForm();
  4. Assembly asmb = Assembly.GetExecutingAssembly();
  5. Object obj = asmb.CreateInstance(className);
  6. Form frm = obj as Form;
  7. this.ShowMenu(frm);
  8. WaitFormService.CloseWaitForm();
  9. }
  10. catch (Exception ex)
  11. {
  12. WaitFormService.CloseWaitForm();
  13. }

接口的使用

参考文章

1. 飘落纸飞机C# winform 多线程中创建等待窗体,2011。

C# 多线程窗体的创建的更多相关文章

  1. C# WinForm 单例模式(例:同一个窗体只创建一次实例)

    //C# WinForm 单例模式(例:同一个窗体只创建一次实例) //打开窗体的事件: Form3 f = Form3.InstanceObject() ; //实例化窗体 f.Focus(); / ...

  2. delphi 窗体的创建和释放

    Delphi中的窗体分为模式窗体和无模式窗体.二者的区别在于,用户可以在无模式窗体和其他窗体之间切换.这样,用户就可以同时工作于一个应用程序的几个部分.Delphi中窗体的初始化有两种情况,动态创建, ...

  3. Java多线程——线程的创建方式

    Java多线程——线程的创建方式 摘要:本文主要学习了线程的创建方式,线程的常用属性和方法,以及线程的几个基本状态. 部分内容来自以下博客: https://www.cnblogs.com/dolph ...

  4. Java:多线程概述与创建方式

    目录 Java:多线程概述与创建方式 进程和线程 并发与并行 多线程的优势 线程的创建和启动 继承Thread类 start()和run() 实现Runnable接口 实现Callable接口 创建方 ...

  5. Qt多线程学习:创建多线程

    [为什么要用多线程?] 传统的图形用户界面应用程序都仅仅有一个运行线程,而且一次仅仅运行一个操作.假设用户从用户界面中调用一个比較耗时的操作,当该操作正在运行时,用户界面一般会冻结而不再响应.这个问题 ...

  6. Java多线程系列-线程创建

    1.怎样创建多线程? Java从语言级别实现多线程,因此实现一个多线程程序很easy.有两种方法能够实现多线程,即继承Thread类和实现Runnable接口.由于Java不支持多继承的原因,建议尽可 ...

  7. Java基础加强之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

  8. Delphi MDI 子窗体的创建和销毁 [zhuan]

    1.如果要创建一个mdi child,先看是否有这个child 存在,如果有,则用它,如果没有再创建 //该函数判断MDI 子窗体是否存在,再进行创建和显示function isInclude(for ...

  9. Java基础之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

随机推荐

  1. websocket IE11 提示SecurityError

    一开始我从网上下载的示例地上localhost:8081 在其它 浏览器下都正常,就在IE11下提示SecurityError, 然后把我把localhost换成IP,就好了. 依次记录下.

  2. mongo 指令

    简单查询1: db.find( {}, {} )  第一个{} 是条件,第二个{}是需要那些属性, db.find( {} )      第二个{}没有,代表返回所有属性 db.find( {age: ...

  3. windows客户端远程访问linux下mysql方法

    windows客户端远程访问linux下mysql方法 1. 改表法.可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 &q ...

  4. ubuntu ftp服务器搭建

    linux ftp服务器部署 1.sudo apt-get install vsftpd   ##下载vsftpd 2.sudo vim /etc/vsftpd.conf  ##vsftpd配置文件 ...

  5. POJ3045 Cow Acrobats

    题意 Farmer John's N (1 <= N <= 50,000) cows (numbered 1..N) are planning to run away and join t ...

  6. 关于SQL的几道小题详解

    关于SQL的几道小题详解 当我们拿到题目的时候,并不是急于作答,那样会得不偿失的,而是分析思路,采用什么方法,达到什么目的,还要思考有没有简单的方法或者通用的方法等等,这样才会达到以一当十的效果,这样 ...

  7. jdk1.8新特性之接口default方法

    众所周知,default是java的关键字之一,使用场景是配合switch关键字用于条件分支的默认项.但自从java的jdk1.8横空出世以后,它就被赋予了另一项很酷的能力——在接口中定义非抽象方法. ...

  8. Unit03: Spring Web MVC简介 、 基于XML配置的MVC应用 、 基于注解配置的MVC应用

    Unit03: Spring Web MVC简介 . 基于XML配置的MVC应用 . 基于注解配置的MVC应用 springmvc (1)springmvc是什么? 是一个mvc框架,用来简化基于mv ...

  9. 配置Jar包及相关依赖Jar包的本地存放路径

    配置Jar包及相关依赖Jar包的本地存放路径 用 maven2 ,pom.xml中设置了依赖,会帮你下载所有依赖的.jar到 M2_REPO 指向的目录. M2_REPO是一个用来定义 maven 2 ...

  10. StreamTool

    public class StreamTool { //从流中读取数据 public static byte[] read(InputStream inStream) throws Exception ...