Results 1 to 8 of 8

Thread: [RESOLVED] Dim t1 As New Threading.Thread(AddressOf VARIABLEHERE)

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Sep 2012
    Posts
    25

    [RESOLVED] Dim t1 As New Threading.Thread(AddressOf VARIABLEHERE)

    Hi all,

    Apologies if this has been answered before, I suppose it's possible that I've been Googling incorrectly, though I did my best to look around for this information before posting.

    I am self-taught, so there's a distinct possibility that I am doing this 100% incorrectly. I have a few vb.net programs which invoke threads pointing to different subs, generally the syntax for this would be as follows:

    vb.net Code:
    1. Public Sub MainSub()
    2.     Dim t1 As New Threading.Thread(AddressOf SecondSub)
    3.     Dim t2 As New Threading.Thread(AddressOf SecondSub)
    4.     t1.Start()
    5.     t2.Start()
    6.     t1.Join()
    7.     t2.Join()
    8. End Sub
    9.  
    10. Public Sub SecondSub()
    11.     'Do some multi-threaded operation here
    12. End Sub

    As far as I can tell, this works perfectly. But imagine if I used that method of spawning threads and I wanted 64 threads (rather than 2) running SecondSub at the same time. You'd have to write down Dim t1 through Dim t64, along with 64 Start()'s, and 64 Join()'s. It's a large chunk of code, and I call multithreading a few times throughout my project. I thought I could minimize this by only writing it once in a Generate_Multithreading sub, and then sending the target sub name into it like this:

    vb.net Code:
    1. Public Sub MainSub()
    2.     Generate_Multithreading("SecondSub")
    3. End Sub
    4.  
    5. Public Sub Generate_Multithreading(ByVal targetSub as String)
    6.     Dim t1 As New Threading.Thread(AddressOf targetSub)
    7.     Dim t2 As New Threading.Thread(AddressOf targetSub)
    8.     t1.Start()
    9.     t2.Start()
    10.     t1.Join()
    11.     t2.Join()
    12. End Sub
    13.  
    14. Public Sub SecondSub()
    15.     'Do some multi-threaded operation here
    16. End Sub

    This causes an error: "'AddressOf' operand must be the name of a method (without parentheses)."

    I am confident that this is because my targetSub variable is a String, and AddressOf doesn't accept strings. So what should I make targetSub in order to make AddressOf happy? Is it even possible to point AddressOf at a variable of any kind?

    If not, maybe I'm just going about the multithread generation stupidly? As I said: I am self taught, and I am willing to admit that I know very little.

    I'd appreciate any advice! Thanks in advance!
    Last edited by RichardG; May 8th, 2017 at 01:07 PM. Reason: Added [RESOLVED] to title. :)

  2. #2
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Dim t1 As New Threading.Thread(AddressOf VARIABLEHERE)

    How about something like this.

    Code:
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim t As Task = Task.Run(Sub()
                                         MainSub(8) 'start 8 threads
                                     End Sub)
            Debug.WriteLine("B1 " & DateTime.Now) 'show done
        End Sub
    
        Private ThreadsStarted As New List(Of Task)
        Private lock As New Object
        Private lockMRE As New Threading.ManualResetEvent(True)
        Public Async Sub MainSub(NumToStart As Integer)
            'only one group at a time
            Threading.Monitor.Enter(lock)
            If lockMRE.WaitOne Then
                lockMRE.Reset()
            End If
            Threading.Monitor.Exit(lock)
            ThreadsStarted.Clear() 'clear the list
            For x As Integer = 1 To NumToStart 'start the tasks
                Dim t1 As Task = Task.Run(Sub()
                                              SecondSub()
                                          End Sub)
                ThreadsStarted.Add(t1) 'add to list
            Next
            Await Task.WhenAll(ThreadsStarted) 'wait for all of the tasks to complete
            'here only when all of the tasks complete
            Debug.WriteLine("main done " & DateTime.Now) 'show done
            'For Each t As task In ThreadsStarted
            '    Debug.WriteLine(t.Status)
            'Next
            lockMRE.Set() 'allow more to run
        End Sub
    
        Public Sub SecondSub()
            'Do some multi-threaded operation here
            Threading.Thread.Sleep(1000) 'simulate work
        End Sub
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

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

    Re: Dim t1 As New Threading.Thread(AddressOf VARIABLEHERE)

    This:
    vb.net Code:
    1. Public Sub MainSub()
    2.     Generate_Multithreading("SecondSub")
    3. End Sub
    4.  
    5. Public Sub Generate_Multithreading(ByVal targetSub as String)
    6.     Dim t1 As New Threading.Thread(AddressOf targetSub)
    7.     Dim t2 As New Threading.Thread(AddressOf targetSub)
    should be this:
    vb.net Code:
    1. Public Sub MainSub()
    2.     Generate_Multithreading(AddressOf SecondSub)
    3. End Sub
    4.  
    5. Public Sub Generate_Multithreading(ByVal targetSub as ThreadStart)
    6.     Dim t1 As New Threading.Thread(targetSub)
    7.     Dim t2 As New Threading.Thread(targetSub)
    The AddressOf operator creates a delegate, i.e. an object that refers to a method. In the case of the Thread constructor, it expects a ThreadStart delegate. You would create the delegate first and pass that to the method and then the method can pass the delegate to the Thread constructor.

    Note that I haven't tested that code but I believe that it should work. It's possible that you would need to create a ThreadStart delegate explicitly rather than implicitly, which would look like this:
    vb.net Code:
    1. Public Sub MainSub()
    2.     Generate_Multithreading(New ThreadStart(AddressOf SecondSub))
    3. End Sub
    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

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Sep 2012
    Posts
    25

    Re: Dim t1 As New Threading.Thread(AddressOf VARIABLEHERE)

    Thank you both for your answers!

    I especially appreciated your post jmcihinney, it answered my question directly and completely, without forcing me to change my approach. I've done some testing this morning, and both the implicit and the explicit delegate creations worked. (And I learned a bit about delegates while I was at it.)

    I've seen you around the web a bunch while googling for various vb.net issues over the last few years, and I've got to say you really seem to know your stuff. As a part-time coder who learns through google searches, I sincerely appreciate all of your help!

  5. #5
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Dim t1 As New Threading.Thread(AddressOf VARIABLEHERE)

    You also don't need to dim each thread individually. You can create a List(Of Threading.Thread) and then create an instance, add it to your list, and repeat as needed.
    somethign along these lines:
    Code:
    Private ThreadList as new List(Of Threading.Thread)
    
    Public Sub MainSub()
        Generate_Multithreading(AddressOf SecondSub)
    End Sub
     
    Public Sub Generate_Multithreading(ByVal targetSub as ThreadStart)
        ThreadList.Add(New Threading.Thread(targetSub))
        ThreadList.Add(New Threading.Thread(targetSub))
    That just adds two, but it could also be in a loop where you can add 4, 3, 5, or 100.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Sep 2012
    Posts
    25

    Re: Dim t1 As New Threading.Thread(AddressOf VARIABLEHERE)

    Oh wow, thank you so much techgnome! My code just shrank by hundreds of lines, this is clearly superior to the way I've been doing this.

    Okay so here's my new code!

    vb.net Code:
    1. Private ThreadList As New List(Of Threading.Thread)
    2.  
    3. Public Sub MainSub()
    4.     Generate_Multithreading(New ThreadStart(AddressOf SecondSub))
    5. End Sub
    6.  
    7. Public Sub Generate_Multithreading(ByVal targetSub as ThreadStart)
    8.     For i = 0 to 63 'Generating 64 Threads
    9.         ThreadList.Add(New Threading.Thread(targetSub))
    10.     Next
    11.  
    12.     For Each Thread In ThreadList
    13.         Thread.Start() 'Start each thread
    14.     Next
    15.  
    16.     For Each Thread In ThreadList
    17.         Thread.Join() 'Waiting for each thread to finish
    18.     Next
    19.  
    20.     ThreadList.Clear() 'Clear the list before re-populating
    21. End Sub
    22.  
    23. Public Sub SecondSub()
    24.     'Do some multi-threaded operation here
    25. End Sub

    You guys rock =D Thank you so much!
    Last edited by RichardG; May 8th, 2017 at 11:00 AM. Reason: Small Errors In Finished Code

  7. #7
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Dim t1 As New Threading.Thread(AddressOf VARIABLEHERE)

    Code:
        Private ThreadList As New List(Of Task)
    
        Public Sub MainSub()
            Generate_Multithreading(New ThreadStart(AddressOf SecondSub))
        End Sub
    
        Public Sub Generate_Multithreading(ByVal targetSub As ThreadStart)
            For i As Integer = 0 To 63 'Generating 64 Threads
                ThreadList.Add(Task.Run(Sub() targetSub()))
            Next
            Task.WaitAll(ThreadList.ToArray)
            ThreadList.Clear() 'Clear the list before re-populating
        End Sub
    
        Public Sub SecondSub()
            'Do some multi-threaded operation here
        End Sub
    I'd use Task, but to each his own.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  8. #8

    Thread Starter
    Junior Member
    Join Date
    Sep 2012
    Posts
    25

    Re: Dim t1 As New Threading.Thread(AddressOf VARIABLEHERE)

    Oh wow, thank you very much for the tip dbasnett.

    I googled the differences and I think you're right, task would be a much better idea, as it would save resources compared to thread.

    The only hold-up for me is that I have to target .net 3.5 with this project, and it doesn't seem that the System.Threading.Tasks namespace is available until 4.0: otherwise I'd swap.

    Good to know for future projects nonetheless!

Tags for this Thread

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