title: ThreadPool - loop until all threads completed in vb.net
body: <p>I'm trying to speed up a code with threads and ThreadPool but I'm not able to wait until all threads are executed before exiting sub.</p>
  
  <p>I've tryed many ways, the code below is my last attempt.
  It waits but not until all threads are ended.</p>
  
  <p>Where I'm wrong?</p>
  
  <pre><code>Public ThrStarted As Integer
  
  Sub Main
  
          ThreadPool.SetMaxThreads(10, 10)
  
          Dim ArrVal() As Object
          For LitiThr% = 0 To Liti.getUpperbound(1)
              Erase ArrVal
              ArrVal = {Liti(3, LitiThr), Liti(0, LitiThr), CInt(Liti(4, LitiThr)), CInt(Liti(1, CicloLitiThr)), CInt(Liti(2, LitiThr))}
  
              ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf mThread), ArrVal)
          Next CicloLitiThr
          Dim workerThreads%
          Dim completionPortThreads%
          Do
              ThreadPool.GetAvailableThreads(workerThreads, completionPortThreads)
  
              Me.lblTotal.Text = workerThreads &amp; " / " &amp; completionPortThreads
              Me.TBox_LitiUpd.Text = LitiUpd.ToString
              Application.DoEvents()
  
          'With This I want to wait until all threads executed but it doesn't seems to work
          Loop Until (ThrStarted - 1) = Liti.getUpperbound(1) And workerThreads = 0
  
  End Sub
  
  
  
  Sub mThread(ByVal ArrVal() As Object) 
  
  
      ThrStarted += 1
  
      'Some code
  
  End Sub
  </code></pre>
  
  <p>I've read many questions/Answers and I found that many tips were for switching to "Parallel.ForEach" but I wasn't able to change my code (It's my first try with threads).</p>
  
  <p>UPDATE:</p>
  
  <p>Following your advice (+1 for the incentive) I changed my code as below but now I'm not able to show status of threads on UI.</p>
  
  <p>I'm afraid that I can't use "await" because I'm using VS2010 express and (on MSDN) I've read:
  "The Async and Await keywords were introduced in Visual Studio 2012."</p>
  
  <p>So, what can I do? </p>
  
  <pre><code>        Dim mDaPass(Liti.getUpperbound(1)) As Object
          Dim mDaIns() As Object
          For LitiThr% = 0 To Liti.getUpperbound(1)
              Erase mDaIns
              mDaIns = {Liti(3, LitiThr), Liti(0, LitiThr), CInt(Liti(4, LitiThr)), CInt(Liti(1, LitiThr)), CInt(Liti(2, LitiThr))}
              mDaPass(LitiThr%) = mDaIns
          Next LitiThr
          Parallel.ForEach(mDaPass, AddressOf mThread)
  
          Task.WaitAll()
  </code></pre>