2

I am using the BackgroundWorker to do the heavy tasks so the UI thread doesn't get blocked. While the BackgroundWorker can send values to the UI thread using the progress-scheme, how can the BackgroundWorker get some values FROM the UI thread?

Either by asking it or simply by the UI thread sending some values to the BackgroundWorker?

Just accessing a variable of the UI thread like UIForm.x within the BackgroundWorker does not work, it does not seem to have access to the UI variables???

Many thanks

user387184
  • 10,953
  • 12
  • 77
  • 147
  • RunWorkerAsync() can take an Object as an argument. Which could be an object of a class you create to store the UI values that the worker needs. – Hans Passant Jan 02 '12 at 13:16
  • Thanks, but I don't need the values just to start the worker - the worker has to get values from the UI thread several times while it is running already. I should have made this clearer in my question... – user387184 Jan 02 '12 at 13:57
  • Then you're doing it wrong. It is utterly unpredictable when the values will change, no point in keeping a worker running and waiting for the user to wake up again. Just start the worker again when such a value changes. – Hans Passant Jan 02 '12 at 14:08
  • The way it works is that in the UI I input a value and this should go to the BackgroundWorker somehow sometime - when is not important – user387184 Jan 02 '12 at 14:16

1 Answers1

5

Other threads than the UI thread are not allowed to access the UI. You probably started the BackgroundWorker with worker.RunWorkerAsync(). You can also start it with worker.RunWorkerAsync(someObject). While the worker is running, you cannot pass new objects, but you can alter the contents of the object itself. Since object types are reference types, the UI thread and the worker thread will see the same object content.

Imports System.ComponentModel
Imports System.Threading

Class BgWorkerCommunication
    Private _worker As BackgroundWorker

    Private Class WorkParameters
        Public text As String
    End Class

    Public Sub DoRun()
        Dim param = New WorkParameters()

        _worker = New BackgroundWorker()
        AddHandler _worker.DoWork, New DoWorkEventHandler(AddressOf _worker_DoWork)
        AddHandler _worker.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf _worker_RunWorkerCompleted)

        param.text = "running "
        _worker.RunWorkerAsync(param)
        While _worker.IsBusy
            Thread.Sleep(2100)
            param.text += "."
        End While
    End Sub

    Private Sub _worker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        Console.WriteLine("Completed")
    End Sub

    Private Sub _worker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        Dim param = DirectCast(e.Argument, WorkParameters)
        For i As Integer = 0 To 9
            Console.WriteLine(param.text)
            Thread.Sleep(1000)
        Next
    End Sub
End Class
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188