Reputation: 75
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
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
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
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