1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    MsgBox("test")
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    BackgroundWorker1.RunWorkerAsync()
End Sub

Once I click the Button1 ,Messagebox appears.When click okay with "Return" (enter) key it appears again and again...But when I click Return key permanently,almost 5 seconds later programs gives me the run time error.

Error is not English in my computer and I translated it.It is nearly mean "BackgroundWorker is busy,can't do two procces in the same time..."

I know that error.It is because of trying to run BackgroundWorker while it is running.In the code it just start with RunWorkerCompleted event.So it can't start again if "Work is not Completed".Who runs the BackgroundWorker ?

  • 1
    It seems a little odd that you're displaying things in the UI directly from a `BackgroundWorker` - is this perhaps an [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) - what's your actual end goal? – James Thorpe Sep 22 '15 at 16:21
  • I am not sure how anyone "presses Return key permanently". Holding the key down will eventually send the click to Button1 instead of the MsgBox you are expecting (you cant press the Msgbox button before it shows!). When that happens, since the code is trying to keep the worker running all the time, you will eventually be trying to start a second instance which is what the message says. Use `Backgroundworker.IsBusy` to see if there it is already running. User interaction though is not what a worker is for. – user3697824 Sep 22 '15 at 16:37
  • Do you want the program to keep running the background worker, or are you saying it is a problem because it keeps running? In other words, why are you holding down the "Return" key? Are you trying to make the message go away, or simply trying to click it very fast? – John Sep 22 '15 at 16:39
  • "When click okay with "Return" (enter) key it appears again and again", is that what you want to happen? – John Sep 22 '15 at 16:41
  • For example,I'm going to code an Ftp chat program.With backgroundworker I read the data in txt file in ftp,when it's done,it must be repeat that code.So user can be online and gets data as soon as possible.This error very confused me...If it appears when bw getting data ? I have to know this error and find some solutions.Btw,chat program was an 'example'. –  Sep 22 '15 at 16:41
  • Does Backgroundworker.IsBusy needed ? I wrote code into BackgroundWorker1_RunWorkerCompleted event. –  Sep 22 '15 at 16:45
  • Yes, `IsBusy` is needed. Study the comment I posted, think about the error message and consider *where* you are getting the runtime error. Context is everything. – user3697824 Sep 22 '15 at 16:58
  • I know `IsBusy` method fixes it.Whatever,I'll change the post. –  Sep 22 '15 at 19:46

1 Answers1

0

You need to read this post first, it talks about the dangers of re-entrancy and how dialogs (like MsgBox) solve the problem.

Which is what it is not doing in your program. A dialog can only be modal against other windows that are created on the same thread. That worker thread doesn't have any. So there is nothing that stops your Enter key press from also being seen by the control that has the focus. Button1. Note how you can simply use the mouse to select your main window and click the button. Kaboom.

That doesn't go wrong often enough as-is, you can help by leaning on the Enter key so it starts repeating. It will usually be detected by the message box window. But not always, there's a split second between DoWork ending and it starting back up. Just enough to give the UI thread a chance to see the keystroke. Now that Enter keypress operates Button1 and it starts the BGW back up again. So does the RunWorkerCompleted event handler, it cannot be started twice. Kaboom.

That's not the only problem with that dialog, you haven't discovered the other failure mode yet. A dialog needs an owner window, one that it can be displayed on top of. That message box does have one, it has to fallback to the desktop window. Now it is crapshoot which window is going to be in front. Could be the dialog, could be your main window. With the message box underneath your main window. The user cannot see it, has no idea that there is one. No taskbar button either.

Long story short: this cannot work. Only display UI on the UI thread. Only use a worker thread to do non-UI related work.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • The second paragraph,it is the answer ! I added `Button2` that does nothing.Wrote `Button2.Focus()` after calling `Backgroundworker1` in the `Button1.Click` event.Error disappeared.Thanks for reply ! –  Sep 22 '15 at 19:44