locked
Cross thread - adding strings to a list box RRS feed

  • Pergunta

  • Hi and thank you in advance for any help you can provide.

     

    I have a need to use threads in my work so I can make simultaneous queries to a sql database (using vb.net 2008).

     

    I have provided a simple example below. Here I have two threads (primary and secondary). Each calls the WriteToListBox subroutine that writes 10 times to listbox1 along with the name of the thread doing the work.

     

    After execution, the Primary thread result is visible in the listbox but the secondary isn't even though I know the secondary thread is firing the WriteToListBox subroutine (I had a messagebox.show statement that printed out listbox1.count after each attempt).

     

    I've spent time with this forum and I still can't find the answer to this puzzle. Any ideas why I can't get the strings created by the secondary thread to show in the listbox?

     

    Regards Bob

     

     

     

    Imports System.Threading

    Public Class Form1

    Dim p As Print = New Print()

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    'Print out on current thread

    Dim primaryThread As Thread = Thread.CurrentThread

    primaryThread.Name = "Primary"

    p.PrintNumbers()

     

    'Print out on secondary thread

    Call PrintOnSecondThread()

    Me.ListBox1.Update()

    Me.ListBox1.Refresh()

    End Sub

     

    Public Sub PrintOnSecondThread()

    Dim secondaryThread As Thread = New Thread(AddressOf p.PrintNumbers)

    secondaryThread.Name = "Secondary"

    secondaryThread.Start()

    End Sub

     

    Public Sub WriteToListBox(ByVal txt As String)

    Me.ListBox1.Items.Add(txt)

    End Sub

    End Class

     

    Public Class Print

    Public Sub PrintNumbers()

    For i As Integer = 0 To 10

    Form1.WriteToListBox(i.ToString & " - " & Thread.CurrentThread.Name)

    Next

    End Sub

    End Class

     

    segunda-feira, 21 de abril de 2008 13:41

Respostas

  • you shouldn't be using the static methods in the first place - this is the problem because you are trying to use an instance which you can't quite access.

     

    what you should be doing is either raising an event to a NEW instance ,or existing instance, of Form1 or passing the form as a parameter to another class then calling the WriteToListBox event.

     

    So...

     

    The PrintNumbers() function, should have a reference to form1, so make a constructor for it which will accept Form1:

     

    Dim _form1 as Form1 = nothing

     

    public sub new (byval form1 as Form1)

       Me._form1 = form1

    end sub

     

    public sub PrintNumbers()

     

    for i as Integer = 0 to 10

       Me._form1.WriteToListBox(..................)

    next

     

    end sub

     

    Now, when you are creating the instance of your Print class, be sure to pass it "Me". this would be the reference to the current form. Example:

     

    Dim printClass as new PrintClass(Me)

     

    then since you are calling directly from another thread, a UI control, you need to invoke it:

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=927342&SiteID=1

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=689966&SiteID=1

     

    so your WriteToListBox() method should look something similar to the following:

     

    declare the delegate globally on the Form class like the following:

     

    public delegate sub addItemDelegate(byval item as String)

     

    public sub WriteToListBox(byval item as String)

     

       if Me.listBox.InvokeRequired then

     

          Dim del as new addItemDelegate(AddressOf Me.WriteToListBox)

          Me.listBox.Invoke(addItemDelegate, new object() { item } )

       else

          Me.listBox.Items.Add(item)

       end if

     

    end sub

     

     

     

    This should fix your problem :-)

    segunda-feira, 21 de abril de 2008 13:52

Todas as Respostas

  • you shouldn't be using the static methods in the first place - this is the problem because you are trying to use an instance which you can't quite access.

     

    what you should be doing is either raising an event to a NEW instance ,or existing instance, of Form1 or passing the form as a parameter to another class then calling the WriteToListBox event.

     

    So...

     

    The PrintNumbers() function, should have a reference to form1, so make a constructor for it which will accept Form1:

     

    Dim _form1 as Form1 = nothing

     

    public sub new (byval form1 as Form1)

       Me._form1 = form1

    end sub

     

    public sub PrintNumbers()

     

    for i as Integer = 0 to 10

       Me._form1.WriteToListBox(..................)

    next

     

    end sub

     

    Now, when you are creating the instance of your Print class, be sure to pass it "Me". this would be the reference to the current form. Example:

     

    Dim printClass as new PrintClass(Me)

     

    then since you are calling directly from another thread, a UI control, you need to invoke it:

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=927342&SiteID=1

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=689966&SiteID=1

     

    so your WriteToListBox() method should look something similar to the following:

     

    declare the delegate globally on the Form class like the following:

     

    public delegate sub addItemDelegate(byval item as String)

     

    public sub WriteToListBox(byval item as String)

     

       if Me.listBox.InvokeRequired then

     

          Dim del as new addItemDelegate(AddressOf Me.WriteToListBox)

          Me.listBox.Invoke(addItemDelegate, new object() { item } )

       else

          Me.listBox.Items.Add(item)

       end if

     

    end sub

     

     

     

    This should fix your problem :-)

    segunda-feira, 21 de abril de 2008 13:52
  • This line should be changed from

      Me.listBox.Invoke(addItemDelegate, new object() { item } )

    to 

      Me.listBox.Invoke(del , new object() { item } )

    terça-feira, 12 de dezembro de 2017 22:41