C# 多线程窗体的创建
从目前已经在项目中工作将近一个月来的情况来看,凡是费时的操作,基本上都要用到多线程的等待窗体、进度提示窗体等实时显示动态的进度信息。而如果直接在主线程的窗体上实时更新信息,就会造成更新太快或者太慢而出现的进程假死现象。为了缓解这些情况,本文就参考一些文章,把他们的智慧总结于此。希望对大家有所帮助。
一、多线程中创建等待窗体
在winform程序开发中,计算机经常会执行一些比较耗时的任务,如大量数据的查询操作、较为复杂的业务处理等,这些任务往往需要耗时几秒到几十秒钟的时间,在这些任务执行期间winform程序窗体不再响应任何鼠标和键盘事件,出现假死状态,用户体验很差。
一个比较好的解决办法是,在这些任务执行期间在界面前端显示一个等待窗体,告诉用户任务正在执行中。
1.1 开发等待窗体
窗体中有一个PictureBox控件和两个Lable控件,PictureBox控件的Image属性为一张动态图片。
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- using System.Threading;
- using NavManager.Common;
- namespace NavManager.Utils
- {
- public partial class WaitForm : Form
- {
- public WaitForm()
- {
- InitializeComponent();
- SetText("");
- }
- private delegate void SetTextHandler(string text);
- public void SetText(string text)
- {
- if (this.label2.InvokeRequired)
- {
- this.Invoke(new SetTextHandler(SetText), text);
- }
- else
- {
- this.label2.Text = text;
- }
- }
- }
- }
等待窗体源码
1.2 提供访问等待窗体的接口
编写类WaitFormService
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Threading;
- using System.Windows.Forms;
- namespace NavManager.Utils
- {
- /// <summary>
- /// Using Singleton Design Pattern
- /// </summary>
- public class WaitFormService
- {
- public static void CreateWaitForm()
- {
- WaitFormService.Instance.CreateForm();
- }
- public static void CloseWaitForm()
- {
- WaitFormService.Instance.CloseForm();
- }
- public static void SetWaitFormCaption(string text)
- {
- WaitFormService.Instance.SetFormCaption(text);
- }
- private static WaitFormService _instance;
- private static readonly Object syncLock = new Object();
- public static WaitFormService Instance
- {
- get
- {
- if (WaitFormService._instance == null)
- {
- lock (syncLock)
- {
- if (WaitFormService._instance == null)
- {
- WaitFormService._instance = new WaitFormService();
- }
- }
- }
- return WaitFormService._instance;
- }
- }
- private WaitFormService()
- {
- }
- private Thread waitThread;
- private WaitForm waitForm;
- public void CreateForm()
- {
- if (waitThread != null)
- {
- try
- {
- waitThread.Abort();
- }
- catch (Exception)
- {
- }
- }
- waitThread = new Thread(new ThreadStart(delegate()
- {
- waitForm = new WaitForm();
- Application.Run(waitForm);
- }));
- waitThread.Start();
- }
- public void CloseForm()
- {
- if (waitThread != null)
- {
- try
- {
- waitThread.Abort();
- }
- catch (Exception)
- {
- }
- }
- }
- public void SetFormCaption(string text)
- {
- if (waitForm != null)
- {
- try
- {
- waitForm.SetText(text);
- }
- catch (Exception)
- {
- }
- }
- }
- }
- }
WaitFormService Class Code
1.3 使用WaitFormService提供的接口
- try
- {
- WaitFormService.CreateWaitForm();
- Assembly asmb = Assembly.GetExecutingAssembly();
- Object obj = asmb.CreateInstance(className);
- Form frm = obj as Form;
- this.ShowMenu(frm);
- WaitFormService.CloseWaitForm();
- }
- catch (Exception ex)
- {
- WaitFormService.CloseWaitForm();
- }
接口的使用
参考文章
1. 飘落纸飞机,C# winform 多线程中创建等待窗体,2011。
C# 多线程窗体的创建的更多相关文章
- C# WinForm 单例模式(例:同一个窗体只创建一次实例)
//C# WinForm 单例模式(例:同一个窗体只创建一次实例) //打开窗体的事件: Form3 f = Form3.InstanceObject() ; //实例化窗体 f.Focus(); / ...
- delphi 窗体的创建和释放
Delphi中的窗体分为模式窗体和无模式窗体.二者的区别在于,用户可以在无模式窗体和其他窗体之间切换.这样,用户就可以同时工作于一个应用程序的几个部分.Delphi中窗体的初始化有两种情况,动态创建, ...
- Java多线程——线程的创建方式
Java多线程——线程的创建方式 摘要:本文主要学习了线程的创建方式,线程的常用属性和方法,以及线程的几个基本状态. 部分内容来自以下博客: https://www.cnblogs.com/dolph ...
- Java:多线程概述与创建方式
目录 Java:多线程概述与创建方式 进程和线程 并发与并行 多线程的优势 线程的创建和启动 继承Thread类 start()和run() 实现Runnable接口 实现Callable接口 创建方 ...
- Qt多线程学习:创建多线程
[为什么要用多线程?] 传统的图形用户界面应用程序都仅仅有一个运行线程,而且一次仅仅运行一个操作.假设用户从用户界面中调用一个比較耗时的操作,当该操作正在运行时,用户界面一般会冻结而不再响应.这个问题 ...
- Java多线程系列-线程创建
1.怎样创建多线程? Java从语言级别实现多线程,因此实现一个多线程程序很easy.有两种方法能够实现多线程,即继承Thread类和实现Runnable接口.由于Java不支持多继承的原因,建议尽可 ...
- Java基础加强之多线程篇(线程创建与终止、互斥、通信、本地变量)
线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...
- Delphi MDI 子窗体的创建和销毁 [zhuan]
1.如果要创建一个mdi child,先看是否有这个child 存在,如果有,则用它,如果没有再创建 //该函数判断MDI 子窗体是否存在,再进行创建和显示function isInclude(for ...
- Java基础之多线程篇(线程创建与终止、互斥、通信、本地变量)
线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...
随机推荐
- websocket IE11 提示SecurityError
一开始我从网上下载的示例地上localhost:8081 在其它 浏览器下都正常,就在IE11下提示SecurityError, 然后把我把localhost换成IP,就好了. 依次记录下.
- mongo 指令
简单查询1: db.find( {}, {} ) 第一个{} 是条件,第二个{}是需要那些属性, db.find( {} ) 第二个{}没有,代表返回所有属性 db.find( {age: ...
- windows客户端远程访问linux下mysql方法
windows客户端远程访问linux下mysql方法 1. 改表法.可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 &q ...
- ubuntu ftp服务器搭建
linux ftp服务器部署 1.sudo apt-get install vsftpd ##下载vsftpd 2.sudo vim /etc/vsftpd.conf ##vsftpd配置文件 ...
- POJ3045 Cow Acrobats
题意 Farmer John's N (1 <= N <= 50,000) cows (numbered 1..N) are planning to run away and join t ...
- 关于SQL的几道小题详解
关于SQL的几道小题详解 当我们拿到题目的时候,并不是急于作答,那样会得不偿失的,而是分析思路,采用什么方法,达到什么目的,还要思考有没有简单的方法或者通用的方法等等,这样才会达到以一当十的效果,这样 ...
- jdk1.8新特性之接口default方法
众所周知,default是java的关键字之一,使用场景是配合switch关键字用于条件分支的默认项.但自从java的jdk1.8横空出世以后,它就被赋予了另一项很酷的能力——在接口中定义非抽象方法. ...
- Unit03: Spring Web MVC简介 、 基于XML配置的MVC应用 、 基于注解配置的MVC应用
Unit03: Spring Web MVC简介 . 基于XML配置的MVC应用 . 基于注解配置的MVC应用 springmvc (1)springmvc是什么? 是一个mvc框架,用来简化基于mv ...
- 配置Jar包及相关依赖Jar包的本地存放路径
配置Jar包及相关依赖Jar包的本地存放路径 用 maven2 ,pom.xml中设置了依赖,会帮你下载所有依赖的.jar到 M2_REPO 指向的目录. M2_REPO是一个用来定义 maven 2 ...
- StreamTool
public class StreamTool { //从流中读取数据 public static byte[] read(InputStream inStream) throws Exception ...