VB.Net - BackgroundWorker running multiple

Jimbo99999 used Ask the Experts™
Good Day Experts!

I have finally figured out and have my background worker operating properly.  I am not sure if there is a better way.  Can you confirm if I am doing this the best way?

My project is complete and I am adding the BGW after the fact.  

1) I put a transparent button on top of an existing button
2) On the click of the transparent button I start the BackgroundWorker
3) The BackgroundWorker DoWork contains the call to the original button click

I have 20-30 buttons I would like to utilize the BackgroundWorker on.  Is there a way to use one BackgroundWorker multiple times?  

This is my first attempt at using it and I appreciate your help.

Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
AndyAinscowFreelance programmer / Consultant

>>Is there a way to use one BackgroundWorker multiple times?  
To do the same task?

1) I put a transparent button on top of an existing button
2) On the click of the transparent button I start the BackgroundWorker
3) The BackgroundWorker DoWork contains the call to the original button click

Erm. Why not do the following
Click the original button and in there start the background worker and in the DoWork run the code that you currently have inside the button click event.  (Also if you have NOT coded your current method correctly you haven't gained any advantage of using a background worker.)
ste5anSenior Developer
Take your time to understand how the background worker makes your UI asynch:

Normally you press a button or interact with your UI and some code is executed immediately. And your UI stops until this code has done his work. Then the control is again transferred to the UI.
Using background worker or any other kind of threading including aysnc/await or task parallels library changes this completely. The UI is used to start any job you want, the code may start running immediately or with a time-shift, but the control is always immediately returned to the UI.

So you cannot simple use a background worker. You need to think about: How should the background worker signal that its job is done? How to avoid to start the same job multiple times? You need also to think about shared resources and race conditions.

In your concrete case: Using 20-30 buttons indicate that you have that much different jobs. Here you need to look at your code, at its structure and then you maybe need 30 different background workers. A


Hello.  Thanks for responding.  The 20-30 buttons are on a tabControl with over 20 tabs.  The issue is either a data retrieval to a datagrid or the export to Excel from the datagrid takes a "long" time in User terms.  When this happens and they try to move the tabControl to get to other things on there desktop it leaves a white trail where it use to be.   So, with the background worker I was able to get rid of that behavior and make them more productive by being able to timeshare.

I was trying to not disturb the original functionality as best I can.  I was thinking with the transparent button over the original button
that has a standard naming convention(btnExcelOrderT) then I know the button under it is named btnExcelOrder). The would allow me to pass the name of the button to the DoWork of the Background worker then call the button click of the button.  I am trying to do this without having to add code or move the code of the button click to the DoWork of BGW.  

But it feels like this is not possible without making multiple BGW's.
AndyAinscowFreelance programmer / Consultant

Sounds like the answer to my question was 'no, different tasks'.
If that is the case then you code one BW per task.  

ps. I'd move the code into the DoWork function and not use transparent buttons.  Your design looks like using sticking plaster rather then fixing it properly.
Public Class BgwResult
    Public Name As String
    Public Result As Object
End Class
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    For Each c As Control In Me.Controls 'or use container control if buttons are in GroupBox, Panel etc
        Dim ctrl = c
        If TypeOf c Is Button Then AddHandler c.Click, Sub(s, args) MyButtonClick(ctrl.Name)
End Sub

Private Sub MyButtonClick(btnName As String)
    Dim worker As New System.ComponentModel.BackgroundWorker
    AddHandler worker.DoWork, AddressOf RunThread
    AddHandler worker.RunWorkerCompleted, AddressOf ThreadComplete
    Me.Controls(btnName).Enabled = False 'avoid pressing button while thread executing
End Sub

Private Sub RunThread(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
    Dim btnName As String = e.Argument.ToString
    Dim bgwr = New BgwResult With {.Name = btnName}
    'Thread starts - perform calculations according button name
    Select Case btnName
        Case "Button1"
            bgwr.Result = btn1Function(5)
        Case "Button2"
            'bgwr.Result = btn2Function("someParam")
            'etc for each button
    End Select
    e.Result = bgwr
End Sub
Private Sub ThreadComplete(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
    Dim bgwr = CType(e.Result, BgwResult)
    'Thread complete - show results according button name
    Select Case bgwr.Name
        Case "Button1"
            TextBox1.Text = bgwr.Result.ToString
        Case "Button2"
            'etc for each button
    End Select
    Me.Controls(bgwr.Name).Enabled = True
End Sub
Private Function btn1Function(someParam As Integer) As Integer
    Return someParam + 1
End Function

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial