WinForm程序中多线程与Timer的结合使用

在一个用户界面中,要求用户提供一个Excel文件的地址,用户界面如下。


当选择好文件后,点击Next按钮后,系统会检查提供的Excel文件的可用性,会调用COM组件分析这个Excel的layout等,如果通过了就切换到另一个Form,如果没有的话就提示用户重新选择。如果这个过程时间很长的话,就会造成用户界面的假死现象,没有任何动静。所以,一般会在Form中用一个正在等待的GIF图片提示用户正在运行中。想要如下的效果。



可是虽然加了这个图片,但是因为是在一个线程中,可能会先执行Button Click方法中的所有逻辑后才去渲染界面,所以此种情况下,依然看不到图片显示,看到的只是一个并不完全的WinForm假死在那里。

此时想到了多线程,使用另外的一个线程去执行检查Excel的可用性的操作。用一个变量来标记第二个线程是否完成,完成后在继续往下操作。

bool isOK = false;
bool isThreadOVer= false;
private void button_Click()
{
    //显示图片的代码
    this.pictureBox.visible = true;
     SecondThread.Start();// 去执行检查逻辑, 完成后把isThreadOver标记为true. 而且如果检查结果Excel可用的话,把全局的isOK设置为true,否则为false
    while(true)   //此时是一个等待的过程,在等待第二个线程完成,则继续主线程的逻辑
    {
        if(isThreadOver)
        {
               if(isOK) {} //销毁这个,显示下一个界面
               else {} //返回这个用户界面,提示重新提供Excel路径
        }
    }
}


设想的是CPU执行主线程极小的一段时间,然后转到副线程极小的一段时间,然后再转回来。但是执行的时候发现,程序执行到死循环的时候就卡在这里了,不转换到副线程。所以,现在又是一种假死现象。

另外的办法就是使用Timer控件来代替死循环。设置一个Timer,而且指定的时间间隔很小如100,它就会不断的去探测变量isThreadOver是否为true,如果为true的话,说明第二线程执行完毕,就结束掉当前的界面,显示下一个界面。

private mytimer_Tick()
{
   if(isThreadOver)
	{
		if(isOK)
		{
			//显示下一个界面,销毁当前界面
		}	
	}
}


这样的话,就能在程序检查Excel可用性的时候,不至于造成主线程中用户可视化界面的阻塞以致于给人程序卡死的感觉。


确实,在不给用户假死现象的用户体验上,Timer控件确实可以有所作用。不过,现在我要更正一下这篇博客提到一个结束点,就是执行到某个线程的死循环的时候是否会卡在那里的问题。经过探讨和自己测试,发项目并不会卡死。

            for (int i = 0; i < 3; i++)
            {
                Thread t = new Thread((x) =>
                {
                    while (true)
                    {
                        try
                        { }
                        catch (Exception)
                        { }
                        finally
                        {
                            for (int m = 0; m < 10000; m++)
                            {
                                Console.WriteLine("aaa");
                            }
                        }

                    }
                });
                t.Start();
           }

           while (true)
           {
             Console.WriteLine("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
           }
上边的代码能够并行运行的,循环并不能导致卡死。特此更正。所以,总结一下这篇博客,当WinForm程序中,check用户输入需要很长时间的时候,如果check逻辑和界面显示在一个线程中的时候,有可能造成界面的假死,所以,此时想到把check逻辑放到另外的线程中。此时如果在界面线程中使用死循环判断check是否完成的话,也是可以的(上边做成更正了),但是死循环毕竟耗资源。所以,可以使用一个Timer去定时的检测isThreadOver,看看check逻辑是否完成,如果完成且符合要求的话,就显示下一个界面。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页