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 ...
随机推荐
- Java并发--并发容器之CopyOnWriteArrayList
原文链接:http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容, ...
- BZOJ2705 SDOI2012 Longge的问题 【欧拉函数】
BZOJ2705 SDOI2012 Longge的问题 Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出∑gcd(i, ...
- 出让执行权:Task.Yield, Dispathcer.Yield
Yield 这个词很有意思,叫做“屈服”“放弃”“让步”,字面意义上是让出当前任务的执行权,转而让其他任务可以插入执行.Task.Dispatcher.Thread 都有 Yield() 方法,看起来 ...
- 重温CLR(十五) 托管堆和垃圾回收
本章要讨论托管应用程序如何构造新对象,托管堆如何控制这些对象的生存期,以及如何回收这些对象的内存.简单地说,本章要解释clr中的垃圾回收期是如何工作的,还要解释相关的性能问题.另外,本章讨论了如何设计 ...
- Sprint第一个冲刺(第四天)
一.Sprint介绍 今天我们完成了点餐界面及美化的任务,是通过TabActivity来实现的,界面可以进行滑动来进行点餐. 下面是实验截图: 任务进度: 二.Sprint周期 看板: 燃尽图:
- “RPC好,还是RESTful好?”
REST 和 RESTful 什么区别?REST,即Representational State Transfer的缩写.翻译过来是表现层状态转换.如果一个架构符合REST原则,就称它为RESTful ...
- php替换 json符号
- qqbot 配置
qqbot 配置 用起来还是挺方便的,使用 pip install qqbot 就可以. 不过找配置文件没注意,以为是在程序目前,原来是在 C:\Users\xxx.qqbot-tmp 目录. 插件可 ...
- 骰子点数概率__dp
骰子点数概率 时间限制:1 秒 内存限制:32 兆 题目描述: 把n个骰子扔在地上,所有骰子朝上一面的点数之和为S.输入n,打印出S的所有可能的值出现的概率. 输入: 输入包括一个整数N(1<= ...
- laravel 中JWT完整使用详解
https://laravel-china.org/articles/10885/full-use-of-jwt