John
John

Reputation: 785

vb.net - call a backgroundworkers runworkerasync method from bw's name as a variable

I have an app that's doing lots of time checks and looping through datatables etc checking for certain values at certain times etc.

The end result is that I have a list(of string) that contains the names of the "schedules" that need running at a particular time. Those names correspond to the names of a set of background workers.

I'm wondering if there is any way I can loop through that list and, using the backgroundworker name which is a string variable, call the corresponding background workers RunWorkerAsync method?

The background workers are already declared before runtime, and their names are static - matched by the names in the list.

I've been looking at the CallByName function, but cant find any usage examples of documentation that show it used in this way, so i'm not sure if I'm heading down a dead end there.

 For Each schedule In run_these_schedules
 CallByName(schedule, BackgroundWorker.RunWorkerAsync)
 Next 

Any help appreciated in advanced!

Upvotes: 1

Views: 356

Answers (2)

Idle_Mind
Idle_Mind

Reputation: 39132

Extending djv's excellent answer, you could search the form for all backgroundworkers in the Load() event and store them in a Dictionary(Of String, BackgroundWorker) for fast lookup:

Private BWs As New Dictionary(Of String, BackgroundWorker)

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    For Each pi As Reflection.PropertyInfo In Me.GetType.GetProperties(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
        Dim obj As Object = pi.GetValue(Me)
        If TypeOf (obj) Is BackgroundWorker Then
            Dim bw As BackgroundWorker = DirectCast(obj, BackgroundWorker)
            BWs.Add(pi.Name, bw)
        End If
    Next
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim run_these_schedules() As String = {"BackgroundWorker1", "BackgroundWorker2", "UnicornsExist"}
    For Each schedule In run_these_schedules
        If BWs.ContainsKey(schedule) Then
            BWs(schedule).RunWorkerAsync()
        Else
            Debug.Print("Schedule not found: " & schedule)
        End If
    Next
End Sub

Upvotes: 3

djv
djv

Reputation: 15774

In the designer they will be declared by default as

Friend WithEvents BackgroundWorker1 As ComponentModel.BackgroundWorker
Friend WithEvents BackgroundWorker2 As ComponentModel.BackgroundWorker
' ...

Looks like a field, however once WithEvents gets added this is a property

So we can use Reflection and get the properties by name

Dim run_these_schedules As New List(Of String) From {"BackgroundWorker1", "BackgroundWorker2"}
For Each schedule In run_these_schedules
    Dim t = GetType(Service1)
    Dim pi = t.GetProperty(schedule,
                           Reflection.BindingFlags.Instance Or
                           Reflection.BindingFlags.Public Or
                           Reflection.BindingFlags.NonPublic)
    Dim bw = DirectCast(pi.GetValue(Me), BackgroundWorker)
    bw.RunWorkerAsync()
Next

Upvotes: 4

Related Questions