|
-
Oct 24th, 2018, 08:39 AM
#1
Thread Starter
New Member
BackgroundWorker Blocking Question
Just wondering why this code blocks:
Code:
Public Class Form1
Dim rand As New Random
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For i = 0 To 500000
BackgroundWorker1.ReportProgress(1, rand.Next(0, 10000))
Next
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
TextBox1.Text = e.UserState
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
End Class
While this code does not block:
Code:
Public Class Form1
Dim rand As New Random
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For i = 0 To 500000
TextBox1.Invoke(Sub()
TextBox1.Text = rand.Next(0, 10000)
End Sub)
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
End Class
-
Oct 24th, 2018, 10:17 PM
#2
Re: BackgroundWorker Blocking Question
BackgroundWorker1_ProgressChanged runs on the UI thread, possibly invoking the entire UI thread instead of just your textbox
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Oct 25th, 2018, 11:37 AM
#3
Re: BackgroundWorker Blocking Question
I haven't played around with BackGroundWorkers, but what I would suggest is that you try putting something like a Sleep(1000) into that loop...and reducing the number of iterations down to maybe 50, or less, cause that would take 50 seconds to run.
If the performance doesn't "block" with the Sleep statement, then it wasn't really blocking without the Sleep statement. What was likely happening is that you are so utterly spamming the UI thread with events that it couldn't respond to anything else.
My usual boring signature: Nothing
 
-
Oct 25th, 2018, 06:18 PM
#4
Re: BackgroundWorker Blocking Question
I've tested your code and I see what you mean. I had a second Button on the form that would change the text in a Label and that Button didn't respond to mouse-overs or clicks when using the first code but responded as though there was no background work going on using the second code.
It would be interesting to try that code using the SynchronizationContext class, which I believe that the BackgroundWorker uses internally. It may be that there's more overhead in using that than Invoke and that uses more time on the UI thread.
-
Oct 26th, 2018, 09:49 AM
#5
Thread Starter
New Member
Re: BackgroundWorker Blocking Question
I did more testing later that day and invoking Textbox1 the loop was much slower than using ReportProgress.
I think the UI thread was just getting overloaded with ReportProgress because the loop was so much faster.
-
Oct 26th, 2018, 10:01 AM
#6
Re: BackgroundWorker Blocking Question
 Originally Posted by danadan
I think the UI thread was just getting overloaded with ReportProgress because the loop was so much faster.
Yeah, it's really intended for occasional progress updates, not constant like that. If you're doing something where you're reporting progress even twice a second then that would be plenty for an average user and not monopolise the UI thread as you're seeing here. More regular progress changes than that couldn't really be followed by a human being anyway so there would be no point.
-
Oct 26th, 2018, 10:44 AM
#7
Re: BackgroundWorker Blocking Question
ReportProgress method returns before the control’s ProgressChanged event has completed. So could even have even moved on before ProgressChanged has even fired. ReportProgress is only meant to report the current state BackGroundWoker is at.
-
Oct 26th, 2018, 09:13 PM
#8
Re: BackgroundWorker Blocking Question
 Originally Posted by ident
ReportProgress method returns before the control’s ProgressChanged event has completed.
With that in mind, it would probably be fairer to compare the use of BeginInvoke rather than Invoke. If you do that then you may well find that the second option becomes faster but also appears to block the UI.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|