-1

I trying to get a reply back from a Function BackgroundWorker however it hits Return before the RunWorkerCompleted has fired. As soon the code hits 'Thread_Load' it fires the Return.

Here, I'm simply getting a String back but the end code would send a SQL command, process it and send back the reply.

Thanks for your help.

I've tried using 'While reply = Nothing' but the code just hangs.

In main form

    Private Sub RibbonButton3_Click(sender As Object, e As EventArgs) Handles RibbonButton3.Click
        Dim NewCall As New TestThreads_SQL_Class
        Dim reply As String
        reply = NewCall.Thread_Load()
        MessageBox.Show(reply)
    End Sub

Then in TestThreads_SQL_Class

Imports System.ComponentModel




Public Class TestThreads_SQL_Class
    Public Class ArgumentType
        Public _a As Int32
        Public _b As Int32
    End Class

    Dim WithEvents BackgroundWorker1 As New BackgroundWorker
    Dim reply As String = Nothing


    Public Function Thread_Load()
        ' Create the argument object.
        Dim args As ArgumentType = New ArgumentType With {
            ._a = 5,
            ._b = 6
        }
        ' Start up the BackgroundWorker1. & Pass argument object to it.
        BackgroundWorker1.RunWorkerAsync(args)
        Return reply
    End Function


    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        ' Do some time-consuming work on this thread.
        System.Threading.Thread.Sleep(1000)
        ' Get argument.
        Dim args As ArgumentType = e.Argument
        ' Return value based on the argument.
        e.Result = args._a * args._b
    End Sub


    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        ' Called when the BackgroundWorker is completed.
        reply = (e.Result.ToString())
    End Sub

End Class
  • 1
    You're missing pieces. See the BackGroundWorker setup [here](https://stackoverflow.com/a/52015773/7444103). This is an asynchrounous operation, `Thread_Load()` is done after it has called `BackgroundWorker1.RunWorkerAsync(args)`. `RunWorkerCompleted` has the result. – Jimi Jun 07 '19 at 15:58
  • The [documentation](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker.runworkerasync?view=netframework-4.8) shows an example on how to wait for the thread. As soon as you call RunWorkerAsync, the main thread continue running while the background thread does it's think. Seems like you might be interested in [Async and Await](https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/concepts/async/) – the_lotus Jun 07 '19 at 15:58
  • 1
    You can't get a "reply" from a worker thread. It trundles for a while, running in the background while your UI keeps motoring. Then it has a result. Whatever code needs that result has to be moved to the RunWorkerCompleted event handler. – Hans Passant Jun 07 '19 at 16:07
  • The actual code to perform this kind of operation, if you don't use the Async/Await pattern as suggested, can be relatively complex. See here: [How to: Implement a Component That Supports the Event-based Asynchronous Pattern](https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0) and the related examples. – Jimi Jun 07 '19 at 16:10
  • Make class `TestThreads_SQL_Class` raise a **custom event** from the RunWorkerCompleted event. The main form can simply subscribe to the event when it creates the instance. Otherwise you need to look at Async/Await as suggested by others... – Idle_Mind Jun 07 '19 at 17:26

1 Answers1

-3

Thank you both for the replies. The below work great.

    While Me.BackgroundWorker1.IsBusy
        ' Keep UI messages moving, so the form remains 
        ' responsive during the asynchronous operation.
        Application.DoEvents()
    End While
  • After re-reading the comments I've reworked the code using Async/Await and the code base is must smaller and much more clearer. Both ran at about the same speed with 15,000 SQL commands to a flat file (SQLite). So YES Async/Await. Again thanks for the replies. – Andy Cheese Jun 09 '19 at 14:01