InvokeRequired, what am I doing wrong?

Arokh

Centurion
Joined
Apr 11, 2006
Messages
124
InvokeRequired, what am I doing wrong? (Across Classes)

I have two classes: The UI and from the other one another thread is started.
The UI is just a Form (form1), ListBox (listbox1) and a Button (button1)
form1.vb
Visual Basic:
Public Class Form1
    Delegate Sub MsgDlg(ByVal Msg As String)
    Dim T As New Thread2

    Public Sub AddEvent(ByVal Msg As String)
        If ListBox1.InvokeRequired Then
            Dim MsgSub As New MsgDlg(AddressOf AddEvent)
            ListBox1.Invoke(MsgSub, Msg)
        Else
            ListBox1.Items.Insert(0, DateTime.Now.ToLocalTime.ToString & ": " & Msg)
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        T.Journey()
    End Sub
End Class
thread2.vb
Visual Basic:
Public Class Thread2
    Dim Locations() As String = {"a", "b", "c"}

    Public Sub Journey()
        Dim Elsewhere As New Threading.Thread(AddressOf Wander)
        Elsewhere.Start()
    End Sub

    Private Sub Wander()
        Dim Location As String

        For Each Location In Locations
            Form1.AddEvent("Reached " & Location)
        Next
    End Sub
End Class

Everytime when AddEvent is called from the other thread and reaches InvokeRequired
it is false and insertig the String into the Listbox doesn't work either,
no error but the String is not added.
 
Last edited:
I played around some more and it worked as soon as I moved the code from Thread2 Class to the main Class (with some ajustments of course).
This way InvokeRequired is true and AddEvent is called again to add the string into the ListBox, as it should.

Now why doesn't it work cross Classes?
And how do I make it work?

This problem is quiet annoying, since in my last project I had to give in and
move a lot of Functions and Subs around in different Classes,
where I normally wouldn't put them.
And needless to say, I don't want to do it again.
So every help is appreciated.
 
The only thing I can imagine being the cause of the problem is VB's default form instances - I've never personally used them (with or without threading).

If you amend your code so it isn't relying on the default instance then things should work fine - I've attached a simple re-hash of your code that does perform as expected.

Visual Basic:
Public Class Form1
    Delegate Sub MsgDlg(ByVal Msg As String)
    Dim T As New Thread2(Me) 'Pass ourselve in to the constructor

    Public Sub AddEvent(ByVal Msg As String)
        If InvokeRequired Then
            Dim MsgSub As New MsgDlg(AddressOf AddEvent)
            ListBox1.Invoke(MsgSub, Msg)
        Else
            ListBox1.Items.Insert(0, DateTime.Now.ToLocalTime.ToString & ": " & Msg)
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        T.Journey()
    End Sub
End Class

Public Class Thread2
    Private _f As Form1 'store a copy of the form we are updating
    Public Sub New(ByVal f As Form1)
        _f = f
    End Sub
    Dim Locations() As String = {"a", "b", "c"}

    Public Sub Journey()
        Dim Elsewhere As New Threading.Thread(AddressOf Wander)
        Elsewhere.Start()
    End Sub

    Private Sub Wander()
        Dim Location As String

        For Each Location In Locations
            _f.AddEvent("Reached " & Location)  'use the stored form rather than the default instance
        Next
    End Sub
End Class
 
Ahh thank you, it is now working and I can finally continue my project.

Just out of curiosity:
If you don't use the default Windows Forms,
how do you create your forms?
Manually without the Formdesigner, or is there another trick to it?

Always trying to learn something new, he he.
 
Déjà vu

The only thing I can imagine being the cause of the problem is VB's default form instances - I've never personally used them (with or without threading).

I don't have anything to add, but...

This thread gave me a little bit of déjà vu, and sure enough Arokh had a similar problem back in January - Progressbar won't change value. The problem then, as now, revolved around the use of default form instance. They should probably be avoided (they aren't very OOP anyway).

:cool:
 
Back
Top