Results 1 to 21 of 21

Thread: [RESOLVED] VB 2005 - Passing methods to a different thread.

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Resolved [RESOLVED] VB 2005 - Passing methods to a different thread.

    I have a form with a text box and a list box. With the text box I can type in my information and pass the text_box.text data to the other thread with no problems and no delegates. If I select the EXACT same text data from the list box and pass the list_box.selecteditem to the other thread I get a threading error. Why does this happen and what do I need to do to fix it?

    Thanks!
    Last edited by tomroth; Apr 7th, 2007 at 07:29 PM. Reason: Clarification

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: VB 2005 - Passing methods to a different thread.

    You should ALWAYS use delegation when accessing controls from worker threads. Some calls will work without it, some will appear to work but not, while others simply won't work. Do the right thing and use delegation EVERY time and you'll never have to work out which is which. Marshalling a method call to the thread that owns a control takes about 5 extra lines of code. That is not a big deal so trying to circumvent it is false economy.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: VB 2005 - Passing methods to a different thread.

    I have no problem using a delegate, but the problem is that a list_box.text is called as a 'Public Overrrides Property Text() as String'. Delegate calls don't like this. How do I call the Delegate?

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: VB 2005 - Passing methods to a different thread.

    Huh? Whether a member is overridden or not makes no difference whatsoever to delegation. This code works exactly as you'd expect it to for any type of control:
    vb Code:
    1. Public Class Form1
    2.  
    3.     Private Delegate Function GetControlTextCallback(ByVal ctl As Control) As String
    4.  
    5.     Private Function GetControlText(ByVal ctl As Control) As String
    6.         Dim result As String
    7.  
    8.         If ctl.InvokeRequired Then
    9.             result = CStr(ctl.Invoke(New GetControlTextCallback(AddressOf GetControlText), ctl))
    10.         Else
    11.             result = ctl.Text
    12.         End If
    13.  
    14.         Return result
    15.     End Function
    16.  
    17.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    18.         Me.GetTextBoxAndListBoxText()
    19.     End Sub
    20.  
    21.     Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    22.         Dim t As New Threading.Thread(AddressOf GetTextBoxAndListBoxText)
    23.  
    24.         t.Start()
    25.     End Sub
    26.  
    27.     Private Sub GetTextBoxAndListBoxText()
    28.         MessageBox.Show("TextBox: " & Me.GetControlText(Me.TextBox1))
    29.         MessageBox.Show("ListBox: " & Me.GetControlText(Me.ListBox1))
    30.     End Sub
    31.  
    32. End Class
    Try creating a new form, add a ListBox, a TextBox and two Buttons, then paste in that code and run it.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: VB 2005 - Passing methods to a different thread.

    But if you hover over the method it is asking for a PROPERTY, not a Sub or Function. You can't put PROPERTY into a delegate call.

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: VB 2005 - Passing methods to a different thread.

    Quote Originally Posted by tomroth
    But if you hover over the method it is asking for a PROPERTY, not a Sub or Function. You can't put PROPERTY into a delegate call.
    Quite right, and nor did I try. You write a method that accesses the property of interest, just as in the code that I provided above.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: VB 2005 - Passing methods to a different thread.

    I'm new to vb 2005, but I got your code to work somehow. I can follow the code but don't really understand how it accesses the list_box.selecteditem method. I'll try to understand it better.
    Thanks for the help.

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    There is no ListBox.SelectedItem method. SelectedItem is a property, not a method, and my code doesn't access it at all. My code is simply an example of how you can access any control member via delegation. You could just as easily declare a method named GetListBoxSelectedItem with a ListBox argument and an Object return value:
    vb Code:
    1. Private Function GetListBoxSelectedItem(ByVal lbx As ListBox) As Object
    2.     Dim result As Object
    3.  
    4.     If lbx.InvokeRequired Then
    5.         result = lbx.Invoke(New GetListBoxSelectedItemCallback(AddressOf GetListBoxSelectedItem), lbx)
    6.     Else
    7.         result = lbx.SelectedItem
    8.     End If
    9.  
    10.     Return result
    11. End Function
    or you can write a similar function for a specific ListBox instance, e.g.
    vb Code:
    1. Private Function GetListBox1SelectedItem() As String
    2.     Dim result As String
    3.  
    4.     If Me.ListBox1.InvokeRequired Then
    5.         result = CStr(Me.ListBox1.Invoke(New GetListBox1SelectedItemCallback(AddressOf GetListBox1SelectedItem)))
    6.     Else
    7.         result = CStr(Me.ListBox1.SelectedItem)
    8.     End If
    9.  
    10.     Return result
    11. End Function
    You can tailor your method and the corresponding delegate (don't forget that the delegate must always have the same signature as the method) to any control and any member(s) of that control, be it property or method.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  9. #9

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    Ok. I'm sorry if I seem slow at understanding this. Would the last examples you gave work in a multi threaded app? I didn't see any delegates in the examples. You're right, .selecteditem is a PROPERTY, so when I declare the delegate, what signature am I following? I am doing this to better myself at work with no schooling and really having a handle on delegate calls seems to me will be very advantageous to my programming. I really appreciate your help with this. Also, methods, events, properties - I get them confused. Sorry.

    Thanks again!!!

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    don't forget that the delegate must always have the same signature as the method
    Here's the method signature from my first example:
    vb Code:
    1. Private Function GetControlText(ByVal ctl As Control) As String
    and here's the corresponding delegate declaration:
    vb Code:
    1. Private Delegate Function GetControlTextCallback(ByVal ctl As Control) As String
    Now here are the method signatures from my last examples:
    vb Code:
    1. Private Function GetListBoxSelectedItem(ByVal lbx As ListBox) As Object
    vb Code:
    1. Private Function GetListBox1SelectedItem() As String
    so what do you suppose the delegate declarations should look like?
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  11. #11

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    Private Delegate Function GetListBoxSelectedItem(byVal lbx as Listbox) As Object

    Private Delegate Function GetListBoxSelectedItem() As String

    So you're making your own methods as opposed to hovering over the control (hope control is correct) and waiting to see what VB tells you? If this is true I am guessing that this is a good intro into OOP? Yes?

    Thanks again!!!

  12. #12
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    You can't have two members with the same name. Your method and delegate have to have different names, although it makes sense to use names that imply that they're linked. Notice in the first example my method is named "GetControlText" and my delegate is named "GetControlTextCallback".
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  13. #13

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    Ohhhh. I see. No duplicate names. Also, from what I see that you are doing, if I delcare a method with something like "As Textbox" or "As Listbox" then does that give me access to all of the events and properties that the object has to offer?

  14. #14
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    The whole point of using delegation is because you can't access members of a control from a worker thread. There's no point having a method return a control because you're just in the same position that you started in: you can't access its members from a worker thread.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  15. #15

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    I understand that. I need to delegate. The signature of the delegate is what is escaping me. That's why I asked about declaring my own method to an object and writing the delegate to that method. The PROPERTY thing isn't liked by delegates and I saw you write a method that uses "...As Listbox) As Object". Is that giving me access to all of what Listbox has to offer?

  16. #16
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    That ListBox is the method argument. It's the ListBox whose member(s) you want to access. By doing that you are able to use a single method for multiple ListBoxes. You pass a ListBox to the method and it will use delegation to access the appropriate member(s) of that ListBox specifically. Pass a different ListBox and you'll access the same member(s) of that ListBox. That's why back in my first example I was able to declare the argument as type Control and then pass a TextBox and a ListBox to the same method. In each case it used delegation to get the Text property of that control.

    If you only have one ListBox then there's no need to write a method that can handle multiple ListBoxes, so you can use a method written for a specific ListBox, just like my second example in post #8. That post contains two examples: the first can be used for multiple ListBox controls while the second is specifically for ListBox1.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  17. #17

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    But where did you access the .selecteditem member? The Listbox has lots of members and I didn't see the direct call to the .selecteditem? I'm sorry, be patient with me. I really am quite intelligent, it's just that the verbage gets very confusing and trying to put it all together is also a bit confusing. I do appreciate your help so very much.

    Thanks!!!

  18. #18
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    Look at post #8.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  19. #19

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    So I could acces the .resetforecolor property, for example, using what you have written? If so, I don't get it! Where do you state which member or property you are looking for???

  20. #20
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    You said you wanted to access the SelectedItem property, so my code in post #8 accessed the SelectedItem property. If you don't want to access the SelectedItem property, but rather you want to access the ResetForeColor method then you would remove the reference to the SelectedItem property and...

    Implementing delegation to access control members is very easy if you use these same steps every time.

    1. Write a method to access the member(s) without delegation, e.g.
    vb Code:
    1. Private Sub ResetControlForeColor(ByVal ctl As Control)
    2.     ctl.ResetForeColor()
    3. End Sub
    4.  
    5. Private Function GetListControlSelectedItem(ByVal lstCtl As ListControl) As Object
    6.     Return lstCtl.SelectedItem
    7. End Function
    2. If your methods have argumentsd or return values then declare a delegate with the same signature:
    vb Code:
    1. Private Delegate Sub ResetControlForeColorCallback(ByVal ctl As Control)
    2.  
    3. Private Delegate Function GetListControlSelectedItem(ByVal lstCtl As ListControl) As Object
    Note that I simply added "Delegate" to the declarations, appended "Callback" to the names and removed the method bodies. If your methods don't have arguments and don't have return values then you don't need to declare your own delegate. You can just use the existing MethodInvoker delegate.

    3. Now implement delegation in your methods. To do that you remove the existing body:
    vb Code:
    1. Private Sub ResetControlForeColor(ByVal ctl As Control)
    2.    
    3. End Sub
    4.  
    5. Private Function GetListControlSelectedItem(ByVal lstCtl As ListControl) As Object
    6.    
    7. End Function
    then add the If block that tests whether delegation is required and implements it if it is:
    vb Code:
    1. Private Sub ResetControlForeColor(ByVal ctl As Control)
    2.     If ctl.InvokeRequired Then
    3.         ctl.Invoke(New ResetControlForeColorCallback(AddressOf ResetControlForeColor), ctl)
    4.     Else
    5.  
    6.     End If
    7. End Sub
    8.  
    9. Private Function GetListControlSelectedItem(ByVal lstCtl As ListControl) As Object
    10.     If lstCtl.InvokeRequired Then
    11.         Return lstCtl.Invoke(New GetListControlSelectedItemCallback(AddressOf GetListControlSelectedItem), lstCtl)
    12.     Else
    13.  
    14.     End If
    15. End Function
    This part follows standard steps too. You test the InvokeRequired property of the control you want to access. If it's True then you're on a worker thread and delagation is required. Call the control's Invoke method and pass an instance of the corresponding delegate created with a reference to the current method. The remaining parameters to the Invoke method are the very same parameters that were passed to the current method.

    4. Finally put your original method body back into the Else block:
    vb Code:
    1. Private Sub ResetControlForeColor(ByVal ctl As Control)
    2.     If ctl.InvokeRequired Then
    3.         ctl.Invoke(New ResetControlForeColorCallback(AddressOf ResetControlForeColor), ctl)
    4.     Else
    5.         ctl.ResetForeColor()
    6.     End If
    7. End Sub
    8.  
    9. Private Function GetListControlSelectedItem(ByVal lstCtl As ListControl) As Object
    10.     If lstCtl.InvokeRequired Then
    11.         Return lstCtl.Invoke(New GetListControlSelectedItemCallback(AddressOf GetListControlSelectedItem), lstCtl)
    12.     Else
    13.         Return lstCtl.SelectedItem
    14.     End If
    15. End Function
    Last edited by jmcilhinney; Apr 9th, 2007 at 10:28 PM.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  21. #21

    Thread Starter
    Addicted Member
    Join Date
    Feb 2007
    Location
    Howell, MI
    Posts
    134

    Re: [RESOLVED] VB 2005 - Passing methods to a different thread.

    It's time for bed here in Michigan. Let me absorb this and get back to you. Thanks so very much for the detailed answers!!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width