Fernando
Fernando

Reputation: 75

Why my backgroundWorker does not work?

i tried to implement a backgroudworker but is does not work in second thread and the form still loking and e can't call the event of my button 2, someone tell me why its happening?

my code:

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;

Upvotes: 1

Views: 3230

Answers (3)

Steve Dignan
Steve Dignan

Reputation: 8560

Looks like you may be reporting progress back to the form at a very rapid rate which would result in the form getting locked up.

Try changing the ThreadProc method like so... for demonstration purposes only, of course:

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 );
    }
}

Upvotes: 4

Edwin de Koning
Edwin de Koning

Reputation: 14387

I think that because you are continuously updating your UI thread by letting your thread report progress 100000 times, your UI thread is too occupied to accept the click event from Button 2. I would lower the amount of reports significantly and see if this has any affect.

Since ProgressBar.Value is an int, this should make no differenece:

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

Upvotes: 1

Adam Houldsworth
Adam Houldsworth

Reputation: 64547

For starters I can say that the background worker will be on another thread allocated from the ThreadPool. It is still possible to lock up your UI though, because when you call the ProgressChanged or RunWorkerCompleted events, they are marshalled back onto the UI thread. Only the DoWork event works on another ThreadPool thread.

If you are not on the UI thread, you cannot access UI elements, like button 2 without a little extra work. To access UI elements from other threads, you need to use Control.Invoke to marshal the call back to the UI thread.

Upvotes: 0

Related Questions