火星文 技术研习社

Noname Cat, Keep Thinking
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

zt WinForm应用程序使用后台线程进行长耗时初始化代码

Posted on 2007-09-21 07:32  剑廿三  阅读(778)  评论(0)    收藏  举报
如果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()); 
      }