多线程实现等待屏(欢迎屏)的实现

      由于代码生成机器人第一版本中未使用多线程,所以在生成代码或操作过程中经常出现“假死”现象,在第二版本升级中将体验度作为重要指标,所以整个加载过程将实现加载进度显示及进度信息提示。

       以下代码参考网友的例子,但网上的例子经过测试问题太多,包括对多线程的处理方面,所以经过改造,实现最终效果,也是最后发布版本所使用的。

特别声明:在多线程调用过程中,尽量不要在构造中使用“CheckForIllegalCrossThreadCalls = false;”,当然对于非常小的工具可以临时使用,在此不主张使用。

1、首先创建WaitFormService.cs类,用于调度等待屏,代码如下:

  1 /// <summary>
  2     /// 等待窗体的操作服务类
  3     /// </summary>
  4     public class WaitFormService
  5     {
  6         private Thread waitThread;
  7         private FrmSplash splashForm;
  8         private delegate void CloseSplashForm();
  9         private static readonly Object syncLock = new object();
 10 
 11         private static WaitFormService _instance = null;
 12         /// <summary>
 13         /// 保证仅有一个实例
 14         /// </summary>
 15         public static WaitFormService Instance
 16         {
 17             get
 18             {
 19                 if (WaitFormService._instance == null)
 20                 {
 21                     lock (syncLock)
 22                     {
 23                         if (WaitFormService._instance == null)
 24                         {
 25                             WaitFormService._instance = new WaitFormService();
 26                         }
 27                     }
 28                 }
 29                 return WaitFormService._instance;
 30             }
 31         }
 32 
 33         /// <summary>
 34         /// 创建一个等待窗实例
 35         /// </summary>
 36         public static void CreateWaitForm()
 37         {
 38             WaitFormService.Instance.CreateForm();
 39         }
 40 
 41         /// <summary>
 42         /// 关闭这个等待窗体
 43         /// </summary>
 44         public static void CloseWaitForm()
 45         {
 46             WaitFormService.Instance.CloseForm();
 47         }
 48 
 49         /// <summary>
 50         /// 设置窗体中的文字内容
 51         /// </summary>
 52         /// <param name="text"></param>
 53         public static void SetWaitFormCaption(string text)
 54         {
 55             WaitFormService.Instance.SetFormCaption(text);
 56         }
 57 
 58         public void CreateForm()
 59         {
 60             if (waitThread != null)
 61             {
 62                 try
 63                 {
 64                     DisposeForm();  //此处实现了委托调用,在创建窗体前检查并释放窗体
 65                     waitThread.Abort();
 66                     waitThread.Join();
 67                     waitThread.DisableComObjectEagerCleanup();
 68                 }
 69                 catch { }
 70             }
 71 
 72             splashForm = new FrmSplash();
 73             waitThread = new Thread(new ThreadStart(delegate() {
 74                 Application.Run(splashForm);
 75             }));
 76             waitThread.Start();
 77         }
 78 
 79         private void DisposeForm()
 80         {
 81             if (splashForm != null && splashForm.InvokeRequired)
 82             {
 83                 CloseSplashForm csf = new CloseSplashForm(DisposeForm);
 84                 this.splashForm.Invoke(csf, null);
 85             }
 86             else
 87             {
 88                 splashForm.Dispose();
 89             }
 90         }
 91 
 92         public void CloseForm()
 93         {
 94             if (waitThread != null)
 95             {
 96                 try
 97                 {
 98                     DisposeForm();
 99                     waitThread.Abort();
100                     waitThread.Join();
101                     waitThread.DisableComObjectEagerCleanup();
102                 }
103                 catch { }
104             }
105         }
106 
107         /// <summary>
108         /// 设置等待屏中的显示文字
109         /// </summary>
110         /// <param name="text"></param>
111         public void SetFormCaption(string text)
112         {
113             if (splashForm != null)
114             {
115                 try
116                 {
117                     splashForm.SetText(text);
118                 }
119                 catch { }
120             }
121         }
122     }
View Code

2、必须创建一个等待窗体,并设置显示标签(当然可以再设置进度条等等),我仅实现标签和一个GIF图片,如下图所示:

代码如下:

 1 public partial class FrmSplash : Form
 2     {
 3         public FrmSplash()
 4         {
 5             InitializeComponent();
 6         }
 7 
 8         private delegate void SetTextHandler(string text);
 9         public void SetText(string text)
10         {
11             if (lbl_Status.InvokeRequired)
12             {
13                 this.Invoke(new SetTextHandler(SetText), text);
14             }
15             else
16             {
17                 this.lbl_Status.Text = text;
18             }
19         }
20     }

3、调用方法,任何时候想要显示信息均调用:WaitFormService.SetWaitFormCaption("执行中,请稍候...");,将“”号中内容换成自己要显示的即可。

说明:不是必须放在try..Catch..finally中,是我因为项目问题才放在这里。

 1            try
 2             {
 3                 WaitFormService.CreateWaitForm();
 4                 WaitFormService.SetWaitFormCaption("执行中,请稍候...");
 5                  //以下为要执行的代码,代码将在主线程执行,同时等待屏将置顶显示并显示设置的内容
 6             }
 7             catch { }
 8             finally
 9             {
10                 WaitFormService.CloseWaitForm();
11             }    

 

posted @ 2013-09-04 21:59  蜗牛跑步  阅读(747)  评论(0编辑  收藏  举报