Jump to content
Xtreme .Net Talk

Recommended Posts

Posted (edited)

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

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

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.

Edited by Arokh
Posted

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.

  • Administrators
Posted

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.

 

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

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

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.

  • Administrators
Posted

You would still use the designer for everything just the same - the difference is in how you create a run-time instance of the form.

 

http://www.xtremedotnettalk.com/showthread.php?t=83092 goes into more detail about using forms under .Net including how to create an instance and also passing information back and forth between multiple forms.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

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:

Never trouble another for what you can do for yourself.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...