zt WinForm应用程序使用后台线程进行长耗时初始化代码
2007-09-21 07:32
302 查看
如果WinForm程序在启动的时候需要进行大量数据操作、大量控件初始化、访问网络等需要用户长时间等待的操作,那么就必须使用欢迎窗口让用户等待。
view plaincopy to clipboardprint?
首先你建立一个Form,里面放一个PictureBox,里面放一个你自己认为漂亮的图。
此PictureBox的Dock设置为Fill,把Form的边框属性设置为None,ShowInTaskbar设置为False.
如果可以的话,在PictureBox上叠加一个Label,用来显示初始化信息。
然后,在你对你的主程序窗口编码并调试完成后,手工修改你的主窗口的InitializeComponent方法,把它从主窗口的构造函数中拿出来,变成一个Internal 类型的方法,由外部调用。
然后设置一个类
public sealed class AppContext : ApplicationContext
{
private BackgroundWorker backWork; // 后台线程
private WelcomeForm welcome; // 欢迎窗口
private MainForm mainForm; // 主程序窗口
// 初始化
public AppContext() : base()
{
Control.CheckForIllegalCrossThreadCalls = false;
// 定义后台线程的基本数据
backWork = new BackgroundWorker();
backWork.WorkerReportsProgress = true;
backWork.DoWork = new DoWorkEventHandler(DoWork);
backWork.ProgressChanged +=
new ProgressChangedEventHandler(ReportProcess);
backWork.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(ThreadCompleted);
// 初始化主窗口
welcomeForm = new WelcomeForm();
// 初始化MainForm, 注意,初始化代码应该从
// MainForm的构造函数中取出,否则将非常耗时
mainFrom = new MainForm();
// 将当前主窗口设定为WelcomeForm
// 当程序执行到这行,将显示欢迎窗口。
base.MainForm = welcomeForm;
// 开始执行后台线程
backWork.RunWorkerAsync(mainFrom); // 用后台线程初始化
}
// ApplicationContext,用于WelcomeForm与MainForm切换
// 当WelcomeForm和MainForm调用Close()方法时,
// 将自动调用此方法
protected override void OnMainFormClosed(object sender, EventArgs e)
{
// 判断当时程序主窗口是哪个
if(sender is WelcomeForm) // 主窗口是Welcome
{
// 此时,后台线程调用完毕
// WelcomeForm 已经调用了Close方法
// 将主窗口设定为MainForm
base.MainForm = this.mainForm;
// 显示主窗口
base.MainForm.Show();
// 将后台线程控制对象取消掉
backWork.Dispose();
}
else if(sender is MainForm)
{
// 此时是主窗口关闭时引发的,
// 现在要执行的就是关闭程序
base.MainForm.Dispose();
base.OnMainFormClosed(sender, e);
}
}
// 后台线程执行的方法,用于初始化
public void DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker back = (BackgroundWorker) sender;
MainForm main = (MainForm) e.Argument;
back.ReportProgress(0, "正在初始化,请稍候...");
main.InitializeComponent(); // 这时才初始化
e.Result = main;
}
// BackgroundWorker 负责调用的方法
// 只有这个方法,后台线程才能访问界面UI
public void ReportProcess(object sender, ProgressChangedEventArgs e)
{
// 后台线程报告进度,
// 此时,主窗体实际上是Welcome,它有个名为statusLable的Label控件
// 用于向客户提供反馈信息
base.MainForm.statusLabel.Text = (string) e.UserState;
}
// 后台线程工作完毕后调用的方法
// 这个方法负责关闭WelcomeForm,打开MainForm
public void ThreadCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Error != null) // 初始化失败,出现错误
{
// 调用错误处理代码,显示错误消息,退出...
}
mainForm = (MainForm) e.Result;
welcomeForm.Close(); // 关闭欢迎窗口
}
}
然后在应用程序的入口点写入:
using System;
public static clase Program
{
public static void Main(string[] args)
{
Application.Run(new AppContext());
}
}
view plaincopy to clipboardprint?
首先你建立一个Form,里面放一个PictureBox,里面放一个你自己认为漂亮的图。
此PictureBox的Dock设置为Fill,把Form的边框属性设置为None,ShowInTaskbar设置为False.
如果可以的话,在PictureBox上叠加一个Label,用来显示初始化信息。
然后,在你对你的主程序窗口编码并调试完成后,手工修改你的主窗口的InitializeComponent方法,把它从主窗口的构造函数中拿出来,变成一个Internal 类型的方法,由外部调用。
然后设置一个类
public sealed class AppContext : ApplicationContext
{
private BackgroundWorker backWork; // 后台线程
private WelcomeForm welcome; // 欢迎窗口
private MainForm mainForm; // 主程序窗口
// 初始化
public AppContext() : base()
{
Control.CheckForIllegalCrossThreadCalls = false;
// 定义后台线程的基本数据
backWork = new BackgroundWorker();
backWork.WorkerReportsProgress = true;
backWork.DoWork = new DoWorkEventHandler(DoWork);
backWork.ProgressChanged +=
new ProgressChangedEventHandler(ReportProcess);
backWork.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(ThreadCompleted);
// 初始化主窗口
welcomeForm = new WelcomeForm();
// 初始化MainForm, 注意,初始化代码应该从
// MainForm的构造函数中取出,否则将非常耗时
mainFrom = new MainForm();
// 将当前主窗口设定为WelcomeForm
// 当程序执行到这行,将显示欢迎窗口。
base.MainForm = welcomeForm;
// 开始执行后台线程
backWork.RunWorkerAsync(mainFrom); // 用后台线程初始化
}
// ApplicationContext,用于WelcomeForm与MainForm切换
// 当WelcomeForm和MainForm调用Close()方法时,
// 将自动调用此方法
protected override void OnMainFormClosed(object sender, EventArgs e)
{
// 判断当时程序主窗口是哪个
if(sender is WelcomeForm) // 主窗口是Welcome
{
// 此时,后台线程调用完毕
// WelcomeForm 已经调用了Close方法
// 将主窗口设定为MainForm
base.MainForm = this.mainForm;
// 显示主窗口
base.MainForm.Show();
// 将后台线程控制对象取消掉
backWork.Dispose();
}
else if(sender is MainForm)
{
// 此时是主窗口关闭时引发的,
// 现在要执行的就是关闭程序
base.MainForm.Dispose();
base.OnMainFormClosed(sender, e);
}
}
// 后台线程执行的方法,用于初始化
public void DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker back = (BackgroundWorker) sender;
MainForm main = (MainForm) e.Argument;
back.ReportProgress(0, "正在初始化,请稍候...");
main.InitializeComponent(); // 这时才初始化
e.Result = main;
}
// BackgroundWorker 负责调用的方法
// 只有这个方法,后台线程才能访问界面UI
public void ReportProcess(object sender, ProgressChangedEventArgs e)
{
// 后台线程报告进度,
// 此时,主窗体实际上是Welcome,它有个名为statusLable的Label控件
// 用于向客户提供反馈信息
base.MainForm.statusLabel.Text = (string) e.UserState;
}
// 后台线程工作完毕后调用的方法
// 这个方法负责关闭WelcomeForm,打开MainForm
public void ThreadCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Error != null) // 初始化失败,出现错误
{
// 调用错误处理代码,显示错误消息,退出...
}
mainForm = (MainForm) e.Result;
welcomeForm.Close(); // 关闭欢迎窗口
}
}
然后在应用程序的入口点写入:
using System;
public static clase Program
{
public static void Main(string[] args)
{
Application.Run(new AppContext());
}
}
相关文章推荐
- 使用 IntelliJ IDEA 开发一般 Java 应用程序时配置 Allatori 进行代码混淆
- MFC 线程创建在使用构造函数进行初始化线程的时候,创建线程实例了,但是线程并没有执行的问题
- Winform使用BackGroundWorker代替线程执行后台代码
- 后台代码中使用Post 进行跳转
- java 通过使用wait和notify进行线程之间通信(代码)
- 后台代码中使用Post进行跳转
- 掌握GCD以及后台永久运行的代码 (使用GCD处理后台线程和UI线程的交互)
- c# 使用后台线程进行日志记录
- 后台代码中使用Post 进行跳转
- 2.使用线程实现数字与代码的交替打印
- 如何:使用后台辅助线程
- 使用PowerDesigner进行代码生成(转载)
- 使用jstack和TDA进行java线程dump分析
- 使用J2EE Spider进行代码生成.
- 使用MyEclipse对远程Jboss下的Java WEB应用程序进行调试
- 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。问题的解决方法!
- 使用GitHub存储代码,进行代码版本管理。
- 使用Java程序控制Barone(Zebra)进行打印的代码
- 在C/C++代码中使用SSE等指令集的指令(5)SSE进行加法运算简单的性能测试
- 使用Symantec代码签名证书对代码进行签名的 5 个理由