0

Basically it's this question but then for VB.net. I need to check the CheckBox state from another thread than the main thread. Solutions for the linked question contain C# code. On-line translators do not yield understandable results.

My code (stripped down to the essential parts):

Public Class UI
    'UI contains CheckBox1.
End Class

Public Class Worker
    Public Sub Input()
        Dim thrMyThread As New System.Threading.Thread(AddressOf Run)
        thrMyThread.Start()
    End Sub

    Public Sub Run()
        If UI.CheckBox1.Checked = True
            MsgBox("True")
            ShellandWait("application.exe")
        Else
            MsgBox("False")
            ShellandWait("application.exe")
        End If
    End Sub

End Class

ShellandWait is a custom function which starts a process and waits until it exits. Because of the ShellandWait I need another thread to keep my UI responsive.

UPDATE
I did find a work around by defining a Public boolean variable at the beginning of the Worker Class, which represents the state of the UI.CheckBox. So:

Public Class Worker
    Public cB As Boolean = UI.CheckBox.Checked
    ... 'Rest of Code
    Public Sub Run()
        If cB = True
            MsgBox("True")
            ShellandWait("application.exe")
        Else
            MsgBox("False")
            ShellandWait("application.exe")
        End If
    End Sub
End Class
Community
  • 1
  • 1
Saaru Lindestøkke
  • 2,067
  • 1
  • 25
  • 51
  • But if, after the ShellandWait, you need to use again the cB var, it could be no more correct. (if your user clicks again on the textbox while your thread is waiting) – Steve May 22 '12 at 07:51
  • Thanks for pointing that out. I'm aware that this is a sloppy work-around. Because I have simplified my code shown here I left some parts out. The methods in the Worker Class are triggered by a "Go" button in the UI. It makes no sense for the user to change controls in the UI while the application is running. If he wants to change a control, the user stops the application with a stop button (kills the .exe process), adjust a control (say, the CheckBox) and then clicks the "Go" button again. – Saaru Lindestøkke May 22 '12 at 07:56
  • The most important thing you left out is that UI is a class derived from Form. Which is the only way you can possibly be using a *type* as though it is an object. And also the reason the code didn't work. On another thread, UI is suddenly a different object. Don't write code like this, it fatally destroys your odds of ever understanding OOP. And getting threading right. – Hans Passant May 22 '12 at 08:08
  • @HansPassant Could you maybe elaborate on "And also the reason the code didn't work"? I am a beginner in VB and this set-up seemed logical to me. What is the proper way of doing such a code? – Saaru Lindestøkke May 22 '12 at 08:10
  • possible duplicate of [Force multi-threaded VB.NET class to display results on a single form](http://stackoverflow.com/questions/273639/force-multi-threaded-vb-net-class-to-display-results-on-a-single-form) – Hans Passant May 22 '12 at 08:10
  • The proper way is to use an object and not a type. Consider learning C# first, it will force you to understand the difference. – Hans Passant May 22 '12 at 08:13

1 Answers1

1

This should work. This code will enable you to access the GUI from worker-threads.

Public Delegate Function GetCheckBoxChekedDelegate(cb As CheckBox) As Boolean

Public Function GetCheckBoxChekedFunction(cb As CheckBox) As Boolean
    Return cb.Checked
End Function

Public Function GetChecked(cb As CheckBox) As Boolean
    If cb.InvokeRequired Then

        Dim del As GetCheckBoxChekedDelegate
        del = AddressOf GetCheckBoxChekedFunction


        Dim parArray() As Object = {cb}

        Return CBool(cb.Invoke(del, parArray))
        'Return CBool(cb.Invoke(del, New Object() {cb}))
        'Return CBool(cb.Invoke(del, {cb}))

    Else
        Return cb.Checked

    End If
End Function

You can use the GetChecked function to get the checked state of the checkbox, the function will works both on the main thread, and on a worker thread.

When the GetChecked function is called from a worker thread the InvokeRequired will return true, so the cb.Checked value is read in the function GetCheckBoxChekedFunction which is called on the main thread by the cb.Invoke(del, {cb}) command.

Max
  • 7,408
  • 2
  • 26
  • 32
  • The `Return CBool(cb.Invoke(del, {cb}))` gives an "Expression expected error" during compile time. Error points to the first curly brace `{` – Saaru Lindestøkke May 22 '12 at 08:20
  • ehm... "it works on my machines"... I'm using VS 2010 targetting .Net 4, if you copy/paste the code in a form, it should work. But it should work anywhere, I've used it tenth of times from the .Net 1.1 years... – Max May 22 '12 at 08:30
  • Where exactly is the error? does VS give you any correction options? – Max May 22 '12 at 08:31
  • I'm compiling using option strict ON, option explicit ON, option infer ON – Max May 22 '12 at 08:32
  • I'm on Visual Studio 2008 Professional Edition, with .Net 3.5. The error points to the first `{` to the left of `cb`. I'm using none of these compiling options. – Saaru Lindestøkke May 22 '12 at 08:34
  • sorry, made a mistake. I compile with Explicit and Infer ON – Saaru Lindestøkke May 22 '12 at 08:36
  • I've updated the code again, using an explicit definition for the parameters array – Max May 22 '12 at 08:43
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/11559/discussion-between-bart-arondson-and-max) – Saaru Lindestøkke May 22 '12 at 08:45