2013-10-25 25 views
1

我有简单的winforms应用程序,我有按钮。按钮点击我正在做这样的为什么主线程在执行后台工作时被挂起

private void Button1_Click(object sender, EventArgs e) 
    { 
     BackgroundWorker bw_Convert = new BackgroundWorker(); 
     bw_Convert.WorkerReportsProgress = true; 
     bw_Convert.DoWork += bw_Convert_DoWork; 
     bw_Convert.RunWorkerCompleted += bw_Convert_RunWorkerCompleted; 
     bw_Convert.ProgressChanged += bw_Convert_ProgressChanged; 
     bw_Convert.WorkerReportsProgress = true; 
     bw_Convert.RunWorkerAsync(); 
    } 

的东西我有以下的后台工作

public void bw_Convert_DoWork(object sender, DoWorkEventArgs e) 
    { 
     for (int i = 0; i <= 1000000; i++) 
     {     
      bw_Convert.ReportProgress((100 * (i)/1000)); 
     } 
    } 
    public void bw_Convert_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    {   

     progressBarControl1.EditValue = e.ProgressPercentage.ToString(); 
    } 

代码通过这样做。为什么我的主线程被挂起,因为我正在处理背景工作者的事情。

+1

你怎么能知道主线被绞死? – Kangkan

回答

2

由于ReportProgress事件处理程序上主线程执行:

到ReportProgress方法的调用是异步的,并立即返回 。 ProgressChanged事件处理程序在创建BackgroundWorker的线程 上执行。

因此,您不断地从后台线程调用ReportProgress,它使您的主线程不断忙于处理此事件。

如果你有很多快速的工作在做背景,然后尝试报告,而不是在每次迭代提高事件仅在每个第n次迭代:

public void bw_Convert_DoWork(object sender, DoWorkEventArgs e) 
{ 
    for (int i = 0; i <= 1000000; i++) 
    { 
     if (i % 10000 == 0) 
      bw_Convert.ReportProgress(i); 
     // do something 
    } 
} 
1

是在UI上执行的ProgressChanged事件线程,以便您可以访问控件。
后台工作程序中的代码在很短的时间内执行,导致许多事件在短时间内引发,使得代码反应就好像它将在UI线程上完全执行一样。

实际上,大部分工作都是在UI线程中完成的,因为更新屏幕上的控件比循环迭代更有效。

相关问题