欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-08-11 10:42:53
在一个用户界面中,要求用户提供一个Excel文件的地址,用户界面如下。 当选择好文件后,点击Next按钮后,系统会检查提供的Excel文件的可用性,会调用COM组件分析这个E...
在一个用户界面中,要求用户提供一个Excel文件的地址,用户界面如下。

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

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

 

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

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

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

[csharp] 

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的话,说明第二线程执行完毕,就结束掉当前的界面,显示下一个界面。

[csharp]  

private mytimer_Tick()  

{  

   if(isThreadOver)  

    {  

        if(isOK)  

        {  

    <span style="white-space:pre">      </span>//显示下一个界面,销毁当前界面  

        }     

    }  

}  

 

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