为什么我的backgroundWorker不起作用?

时间:2011-05-17 14:51:18

标签: c# winforms backgroundworker

我试图实现一个backgroudworker,但是在第二个帖子中不起作用,表单仍然在loking,而且e无法调用我的按钮2的事件,有人告诉我它为什么会发生?

我的代码:

public Form1()
{
  InitializeComponent();
  backgroundWorker1.DoWork += 
    new DoWorkEventHandler(backgroundWorker1_DoWork);
  backgroundWorker1.ProgressChanged += 
    new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
  backgroundWorker1.RunWorkerCompleted += 
    new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
  backgroundWorker1.WorkerReportsProgress = true;
}

void backgroundWorker1_RunWorkerCompleted(object sender, 
  RunWorkerCompletedEventArgs e)
{
  MessageBox.Show("Work is done");
}

void backgroundWorker1_ProgressChanged(object sender, 
  ProgressChangedEventArgs e)
{
  this.progressBar1.Value = e.ProgressPercentage;
}

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
  ThreadProc();
}

private void button1_Click(object sender, EventArgs e)
{
  backgroundWorker1.RunWorkerAsync();
}

void ThreadProc()
{
  //simulate work
  for (int i = 0; i < 100000; ++i)
  {
    int total = i / 1000;
    backgroundWorker1.ReportProgress(total);
  }
}

private void button2_Click(object sender, EventArgs e)
{
  MessageBox.Show("Another thread");
}

TKS;

3 个答案:

答案 0 :(得分:4)

看起来您可能会以非常快的速度向表单报告进度,这会导致表单被锁定。

尝试更改ThreadProc方法,仅用于演示目的:

void ThreadProc ()
{
    //simulate work
    for ( int i = 0; i < 100000; ++i )
    {
        Thread.Sleep( 1 ); // this should allow the form to breath a little :)
        int total = i / 1000;
        backgroundWorker1.ReportProgress( total );
    }
}

答案 1 :(得分:1)

我认为,因为你通过让你的线程报告进度100000次来不断更新你的UI线程,你的UI线程太忙了,不能接受来自Button 2的click事件。我会显着降低报告的数量,看看是否这样有任何影响。

由于ProgressBar.Value是一个int,因此不应该有区别:

  for (int i = 0; i < 100; i++)
  {
    backgroundWorker1.ReportProgress(i);
  }

答案 2 :(得分:0)

对于初学者,我可以说后台工作者将在ThreadPool分配的另一个线程上。尽管如此,仍然可以锁定您的UI,因为当您调用ProgressChangedRunWorkerCompleted事件时,它们会被编组回UI线程。只有DoWork事件适用于另一个ThreadPool主题。

如果您在UI线程上,则无法访问UI元素,例如按钮2,而无需额外的工作。要从其他线程访问UI元素,您需要使用Control.Invoke将调用封送回UI线程。

相关问题