线程与WinForm设计,防冻结,卡住窗体

2013-07-10

卡住很有可能是因为在窗体的Invoke里进行了大量运算。

一般情况,在线程中就仅仅进行和窗体无关的计算,必要时,使用Invoke进行一些窗体状态的更新,这样完全不会导致卡住冻结。

2010-09-25 18:57更新:根据各位朋友的回复,做了一些更新。

加入了BackgroundWorker和MethodInvoker

 

有时候我们在窗体的执行方法中,会延迟很久,那样就会造成操作窗体(界面)卡住(冻结)的情况出现,这样的用户体验非常糟糕。

在使用线程操作,则可能会避免这种情况。

因此我做了一个测试。

在这方面的设计,我也是初学者,因此,有不对的地方,请前辈指点迷津。

 

线程与WinForm设计,防冻结,卡住窗体 

 

///   <summary>
///  执行的主逻辑
///   </summary>
///   <param name="obj"></param>
private   void  RunMethod( object  obj)
{
    ThreadTest tt 
=   new  ThreadTest();
    
int  curValue  =   0 ;
    
for  ( int  i  =   0 ; i  <   20 ; i ++ )
    {
        curValue 
=  tt.GetRandomNum();
        
// 不添加5的项,主要为了添加业务复杂性
         while  (curValue  ==   5 )
        {
            Thread.Sleep(
2000 ); // 制造延迟,测试是否会冻结(卡)主窗口
            curValue  =  tt.GetRandomNum();
        }
        Thread.Sleep(
2000 ); // 制造延迟,测试是否会冻结(卡)主窗口
        
        
if  ( this .InvokeRequired)
        {                   
            
this .Invoke( new  MethodInvoker( delegate ()
            {
                
this .lsbShow.Items.Add(curValue);
                
this .lsbShow.SelectedIndex  =  lsbShow.Items.Count  -   1 ;
            }));
        }
        
else
        {
            lsbShow.Items.Add(curValue);
        }
    }
    
this .Invoke( new  MethodInvoker( delegate ()
    {
        
this .btnRun.Enabled  =   true ;
        
this .btnThread.Enabled  =   true ;
        btnBackgroundWorker.Enabled 
=   true ;
        
this .lsbShow.Items.Add( " Done " );
        
this .lsbShow.SelectedIndex  =  lsbShow.Items.Count  -   1 ;
    }));
}

 

 

用到的测试类

 

public   delegate   void  CommonDelegate();
public   class  ThreadTest
{
    
public  ThreadTest() {  }
    
public   int  GetRandomNum()
    {
        Random rd 
=   new  Random();
        
return  rd.Next( 1 10 );
    }
}

 

调用按钮事件

 

 

private   void  btnRun_Click( object  sender, EventArgs e)
{
    RunStart();
    ThreadPool.QueueUserWorkItem(
new  WaitCallback(RunMethod));            
}

private   void  btnThread_Click( object  sender, EventArgs e)
{
    RunStart();
    Thread td 
=   new  Thread( new  ParameterizedThreadStart(RunMethod));
    td.Start(
"" );            
}
private   void  RunStart()
{
    lsbShow.Items.Clear();
    btnRun.Enabled 
=   false ;
    btnThread.Enabled 
=   false ;
    btnBackgroundWorker.Enabled 
=   false ;
}

private   void  btnBackgroundWorker_Click( object  sender, EventArgs e)
{
    RunStart();
    
using  (BackgroundWorker bw  =   new  BackgroundWorker())
    {
        bw.DoWork 
+=   new  DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerAsync();
    }
}
void  bw_DoWork( object  sender, DoWorkEventArgs e)
{
    RunMethod(
"" );
}

 

 

测试源码http://files.cnblogs.com/yelaiju/WinFormSynTest.rar

你可能感兴趣的:(WinForm)