Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

vb.net threading

Posted on 2011-09-13
9
Medium Priority
?
372 Views
Last Modified: 2012-05-12
Hi, I am new to threading and wanted to see how I could implement into one of my windows apps. So I do something like that shown below (running the same sub mySub from different threads).

But, as soon as I start to do that, I realise that I've no idea what that it's actually going to do exactly and I'm sort of thinking 'how could that possibly work'. I'm thinking these threads are going to intefere with eachother and perhaps I should be starting three instances of the class with sub mySub instead of having three threads working on the same sub in the same class? I'm assuming all the variables would keep getting reset by the different threads so passing the parameters becomes pointless (i.e. you pass the parameter blnRateAll which is set to True for thread one, but then thread 2 starts up and sets it False for instance, and now thread 1 see's it at False instead of True?).

So, how exactly would you want to set something like this up? Three threads running the same subroutine? Also, I'm getting cross thread errors with SelectSheet which is another form. For instance, it can't set lstSelectSheet itself because of the cross thread error. I had previously found some code creating a delegate sub to invoke the label on that form no matter what thread called it which seemed to work ok, so I guess I would have to do something similar again?


Sub ThreadStart()

      Dim alParam As New ArrayList
      Dim paramTS As New ParameterizedThreadStart(AddressOf mySub)
      Dim t1 As Thread = Nothing
      Dim t2 As Thread = Nothing
      Dim t3 As Thread = Nothing

      'Create parameter array for the thread
      Dim d1 As New SelectSheet
      d1.lblSelectSheet.Text = "Please put in file 1 name"
      d1.ShowDialog()
      alParam.Add(d1.lstSelectSheet.SelectedItem.ToString())
      alParam.Add(True) 'for blnRateAll
      alParam.Add(True) 'for blnFirstPass
      alParam.Add(False) 'for blnSecondPass
      alParam.Add(False) 'for blnFinalPass
      d1.Dispose()

      t1 = New Thread(paramTS)
      t1.Start(alParam)


      Dim d2 As New SelectSheet
      d2.lblSelectSheet.Text = "Please put in file 2 name"
      d2.ShowDialog()
      alParam(0) = d2.lstSelectSheet.SelectedItem.ToString()
      alParam(2) = False : alParam(3) = True

      t2 = New Thread(paramTS)
      t2.Start(alParam)


      Dim d3 As New SelectSheet
      d1.lblSelectSheet.Text = "Please put in file 3 name"
      d3.ShowDialog()
      alParam(0) = d3.lstSelectSheet.SelectedItem.ToString()
      alParam(3) = False : alParam(4) = True

      t3 = New Thread(paramTS)
      t1.Start(alParam)


   End Sub

Open in new window

0
Comment
Question by:AidenA
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
9 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 36529391
Also, I'm getting cross thread errors with SelectSheet which is another form.
This is because you are trying to update the GUI from a thread other than the one the GUI was created on--typically, the main thread. You have to invoke a delegate in order to update your GUI from a different thread.

The big thing with threading is the management of shared resources and/or objects. Any time you have something being shared between threads, there is the potential to encounter deadlocks and race conditions. These scenarios are what you need to account for in your code. Most often, the way you handle this is through some sort of locking mechanism. This locking mechanism is what protects your critical section, the part of code that must only allow one thread to be executing at any given time, from multiple threads accessing the shared resources/objects.
0
 
LVL 18

Expert Comment

by:Dennis Aries
ID: 36529413
Multithreading is a large subject, not something that can be explained in a mere answer. I would suggest reading Microsoft MSDN on the subject to get in-depth information.

0
 

Author Comment

by:AidenA
ID: 36529818
yeah, have been reading a bit more there and this is where i am so far (see below).

So, i think i sort of got it working. Had to put synclock onto mySub to avoid the issues you mention, and then put the code below into my main function (and changed some things around to avoid th GUI issue... but I can solve that part I think)

That seemed to more or less solve the issue but I noticed that thread t3 was for some reason running before t2 which was causing a problem. That was ok, I can remove the reason why they must run in order. But, as a consequence, I need the application to wait at a particular point for threads t1, t2, and t3, to terminate before running the final part of the code (which is a cleanup routine).

So, reading a bit, seems like I need thread.join to do this and you can see that in my code below. However, when i ran it, t1.join or t2.join or t3.join never actually completes. It waits for an indeterminate amount of time. So, reading a bit further I think the reason for this is the thread is not terminating. MySub has an end... so I don't know why this would be?

Any ideas why thread.join is not completing?
Dim alParam As New ArrayList
      Dim paramTS As New ParameterizedThreadStart(AddressOf mySub)
      Dim t1 As Thread = Nothing
      Dim t2 As Thread = Nothing
      Dim t3 As Thread = Nothing

      'Create parameter array for the thread
      Dim d1 As New SelectSheet(glWorksheets)
      d1.lblSelectDHLSheet.Text = "Please select the r189 for customer 41335."
      d1.ShowDialog()
      alParam.Add(d1.lstSelectSheet.SelectedItem.ToString())
      alParam.Add(True) 'for blnRateAll
      alParam.Add(True) 'for blnFirstPass
      alParam.Add(False) 'for blnSecondPass
      alParam.Add(False) 'for blnFinalPass
      d1.Dispose()

      t1 = New Thread(paramTS)
      t1.Start(alParam)

      Dim d2 As New SelectSheet(glWorksheets)
      d2.lblSelectDHLSheet.Text = "Please select the r189 for customer 25933."
      d2.ShowDialog()
      alParam(0) = d2.lstSelectSheet.SelectedItem.ToString()
      alParam(2) = False 'for blnFirstPass
      alParam(3) = True 'for blnSecondPass

      t2 = New Thread(paramTS)
      t2.Start(alParam)

      Dim d3 As New SelectSheet(glWorksheets)
      d3.lblSelectDHLSheet.Text = "Please select the r189 for customer 10929."
      d3.ShowDialog()
      alParam(0) = d3.lstSelectSheet.SelectedItem.ToString()
      alParam(3) = False 'for blnSecondPass
      alParam(4) = True 'for blnFinalPass

      t3 = New Thread(paramTS)
      t3.Start(alParam)

      'make threads wait before we cleanup the references
      Dim blnT1 As Boolean = t1.Join(50000)
      Dim blnT2 As Boolean = t2.Join(50000)
      Dim blnT3 As Boolean = t3.Join(50000)

Open in new window

0
Amazon Web Services EC2 Cheat Sheet

AWS EC2 is a core part of AWS’s cloud platform, allowing users to spin up virtual machines for a variety of tasks; however, EC2’s offerings can be overwhelming. Learn the basics with our new AWS cheat sheet – this time on EC2!

 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 36529921
Any ideas why thread.join is not completing?
Without seeing the complete code, that is going to be difficult to diagnose.

You might find it easier to work with the ThreadPool than to manage the creation of threads yourself.
0
 

Author Comment

by:AidenA
ID: 36530817
yeah, but need to learn how to use threads... once I have a decent understanding I'll probably just simplify it and use threadpool or just a background worker thread for the UI or however you're supposed to do it.

But I just want to figure out why thread.join isn't working first. It actually works ok if I make mySub a simple subroutine which doens't really do anything. All threads join correctly. So the problem is in mySub which is a subroutine which automates excel... so it is working on excel objects. I noticed that t1 and t2 joined ok if I moved the opening of an excel file into the main thread (i.e. the code  wb = xlApp.Workbooks.Open("myexceldoc.xls") is moved out of mySub and called before creating the threads).

So again, not sure what was causing that error, but that solved it... I think. But not sure why t3 which is also calling mySub and is performing more or less the same actions as far as I can tell, is not joining.

I mean, how do I even go about trying to see where the error is? Is there a way of seeing exactly where the thread t3 is? What I can see right now is that it doesn't join... but I don't know where exactly it currently is? How do I debug this issue?

Thanks
0
 

Author Comment

by:AidenA
ID: 36530909
well surprisingly I tracked down the error actually... was able to just wait until t1 and t2 would have definitely finished and then debug so I could be sure I was on t3...

Error is coming from

SetProgress_ThreadSafe(Me.lblStatusLabel, "Closing Files", ProgressBar1, ProgressBar1.Value + 1)

which is the code I was using to avoid the GUI error in the beginning. There is the delegate at the beginning;

Delegate Sub SetProgress(ByVal lbl As Label, ByVal txt As String, ByVal pgb As ProgressBar, ByVal intProgress As Integer)

and the sub itself

Private Sub SetProgress_ThreadSafe(ByVal lbl As Label, ByVal txt As String, ByVal pgb As ProgressBar, ByVal intProgress As Integer)
      ' InvokeRequired required compares the thread ID of the calling thread to the thread ID of the creating thread.
      ' If these threads are different, it returns true.
      If lbl.InvokeRequired Then
         Dim MyDelegate As New SetProgress(AddressOf SetProgress_ThreadSafe)
         Me.Invoke(MyDelegate, New Object() {lbl, txt, pgb, intProgress})
      Else
         lbl.Text = txt
         pgb.Value = intProgress
      End If

... and on t3 it seemed to fail on the line Me.Invoke(MyDelegate, New Object() {lbl, txt, pgb, intProgress})

So, that code works fine with t1 and t2... does that info help you identify what the error could be?

0
 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 1000 total points
ID: 36530935
Change:

   Me.Invoke(...)

To:

   Me.BeginInvoke(...)

Invoke() is synchronous so it can cause deadlock issues when Join() becomes involved....
0
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 1000 total points
ID: 36530965
Is there a way of seeing exactly where the thread t3 is?
I think Idle_Mind's got you covered for your error, but to answer this question: you do have the Threads debug window (Debug->Threads). You should be able to set a breakpoint in your threaded function as well. It will hit for each thread, but in combination with the Threads window you should be able to tell which thread you are currently inspecting.
0
 

Author Closing Comment

by:AidenA
ID: 36535331
yep that did it. thanks for the info!

Aiden
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question