Results 1 to 22 of 22

Thread: [RESOLVED] How to handle two or more sub routines at a time

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Mar 2021
    Posts
    21

    Resolved [RESOLVED] How to handle two or more sub routines at a time

    Hello there,

    I am having some problems to handle/run two Subfunctions at a time. Any help would be highly appreciated.

    This is my PictureBox click event:

    Code:
    Sub PbFSGClick(sender As Object, e As EventArgs)
    		Dim con As MsgBoxResult = MsgBox("Do Tasks?",vbYesNo)
    			If con = vbYes Then
    				
    				timerforall.Start()
    
                                 'Thread1 and Thread2 are declared as Thread as global variables
    				Thread1 = New Thread(AddressOf Task1)
    				Thread1.Start()
    				
    				Thread2 = New Thread(AddressOf Task2)
    				Thread2.Start()				
    
    				timerforall.Stop()
    			Else 
    				MsgBox("Nothing to do")
    			End If
    	End Sub
    'Timer which runs all the time in background
    Code:
    Sub TimerforallTick(sender As Object, e As EventArgs)
    		Blink = Not Blink
    	End Sub
    'Sub-function1
    Code:
    Sub Task1()
    				
    		If Blink Then
    			pbFSG.Image = iLFSG.Images(1)
    		Else 
    			pbFSG.Image = iLFSG.Images(0)
    		End If
    
    	End Sub
    'Sub-function2
    Code:
    Sub Task2()
    				
    		If Blink Then
    			pbGSF.Image = iLGSF.Images(1)
    		Else 
    			pbGSF.Image = iLGSF.Images(0)
    		End If
    
    	End Sub
    I have two sub-functions Task1() and Task2() which i would like to execute at the same time after clicking the picturebox pbFSG and selecting the "yes" command from msgbox.

    My problem is nothing happens when I run this code.
    How am I supposed to achieve my goal?

    Best regards
    Krishna

  2. #2
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    10,122

    Re: How to handle two or more sub routines at a time

    Your PictureBox's click event is missing the event handler at the end:
    Code:
    Sub PbFSGClick(sender As Object, e As EventArgs) Handles pbFSG.Click
        '...
    End Sub

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Mar 2021
    Posts
    21

    Re: How to handle two or more sub routines at a time

    Hello there,
    Thank you for your response.
    Actually, I am using 'SharpDevelop' IDE for this application and not Visual Studio.

    It throws the following error after adding the part you suggested
    Attachment 180401

    English translation of the error is:
    "The handles clause requires a WithEvents variable defined in the containing type or one of its base types. BC30506. "
    Please let me know if there is any other way to achieve what i want.

    Best regards
    Krishna

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,940

    Re: How to handle two or more sub routines at a time

    It doesn't matter. You can write .NET using NotePad if you want to. The code files are just text, and the IDE just gives you tools to help make it easier to edit that text.

    So, the error shows that you didn't declare the timer correctly, which could be remedied, but I think there's a greater problem. You have two threads, but the threads do nothing more than interact with the UI. That's a bad thing to do from a thread. Normally, that will raise cross-threading exceptions, which you could get around in various ways, but you just shouldn't get around them. There is no purpose for using threads in this case. A thread should be used when you have some code that will take a fair amount of time, and which can be run behind the scenes with little or no impact on the UI. The code you are showing in the threads will run almost instantly and is entirely about UI impact, so that work is totally different from what you should be doing with threads.

    All you need for this is a single timer, which you already have. Move the code from the thread methods into the tick event handler and get rid of the threads. Then, add the Handles clause onto all your event handlers, and wherever you have declared the controls, they should be declared like this:
    Code:
    Private WithEvents pbFSG As PictureBox
    That may not totally match the declarations you have. They might be Public or Friend rather than Private, and they may create the control on the same line as the declaration, but the key point is that you are missing the WithEvents, which is what the error message is telling you.
    My usual boring signature: Nothing

  5. #5
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    10,122

    Re: How to handle two or more sub routines at a time

    There are quite a few problems with your code that I wasn't going to address in my original post because I felt that it was outside the scope of your original question. However, after your last post, I think it may be warranted for me to elaborate.

    To address your immediate issue, if you are creating the control via code rather than via a designer, then you have two options:
    1. Use the WithEvents keyword when the control is declared
    2. Use the AddHandler statement


    For option 1, it is as simple as:
    Code:
    Private WithEvents PbFSG As New PictureBox
    For option 2, you would need to add the following line in your Form's constructor or Load event:
    Code:
    AddHandler PbFSG.Click, AddressOf PbFSGClick
    Now onto the issues that I immediately saw. First off, do not use MsgBox or vbYesNo. It is a legacy Visual Basic holdover. Use MessageBox.Show and the MessageBoxButtons enumeration.

    Secondly, your threads are messing with the UI without doing anything else. If this is really your code and not just a snapshot of it, get rid of the threads all together and move the code inside the timerforall's Tick event.

    Finally, your timer doesn't always run in the background. It is only running when the user clicks on Yes in your dialog and then it only runs after the 2 threads run. It doesn't look like you need a timer at all.

    Take a look at this example:
    Code:
    Private WithEvents PbFSG As New PictureBox
    Private _blink As Integer = 0
    Private Sub PbFSGClick(sender As Object, e As EventArgs) Handles PbFSGClick
        If (MessageBox.Show("Do Tasks?", "Do Task", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes) Then
            _blink = If(_blink = 0, 1, 0)
            pbFSG.Image = iLFSG.Images(_blink)
            pbGSF.Image = iLGSF.Images(_blink)
        End If
    End Sub
    Last edited by dday9; Mar 3rd, 2021 at 11:05 AM.

  6. #6
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    33,286

    Re: How to handle two or more sub routines at a time

    Actually, I think they do want the timer. I think the original intent was to get the images to "blink" between the two states. The timer changes the blink state, the threads were then supposed to update based on the new state. I think it was an over complicated to something simple. Leave the timer in, after changing the blink boolean, then call Task1 and Task2... the images will change. When the timer expired again, the blink flag is set back, Task1 and Task2 are called again, and the images flipped back.

    -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??? *

  7. #7
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,940

    Re: How to handle two or more sub routines at a time

    Yeah, that's where I was going. I didn't look at when the timer started, but using threads for this is beyond pointless and right into being 'a bad thing to do'. It's cross threading, on the face of it, so they'd at least have to take some action to avoid that, and there is no action that is particularly worth taking.
    My usual boring signature: Nothing

  8. #8

    Thread Starter
    Junior Member
    Join Date
    Mar 2021
    Posts
    21

    Re: How to handle two or more sub routines at a time

    Hello Everyone,

    Thank you for your responses.
    To be honest I am new to VB.Net and don't have much idea of how things work in here. I wanted to apply the idea of multithreading to handle more than one task at a time, which I found on the Internet. The code from my first post was just a simple idea of multithreading with one extra timer, that I tried before implementing it in my application which didn't work and I posted it here so that I would know where the problem really was.

    I would again like to thank you all for all this information. But still, I am unable to solve my problem.
    Here is the real code of my application and the idea behind this code.

    Code:
    'Clickevent of picturebox of the sensor to send the messages
    	Sub PbFSGClick(sender As Object, e As EventArgs) 'Handles pbFSG.Click
    		'If Access = True Then
    			If (MessageBox.Show("Configure Tilt Sensor?", "Tilt Sensor Configuration", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes) Then
    				timerforall.Start() 'Start the timer, change the state of "Blink" variable according to timer interval
    				FSGBlink()			' changes the image of picturebox according to Blink variable from timer
    				Thread3 = New Thread(AddressOf FSG) 'Thread with address of sub function to send CAN messages which take some time 
    				Thread3.Start()				'start the thread
    				timerforall.Stop()			'stop the timer/stop changing the image in picturebox
    			Else 
    				MsgBox("Select the sensor to be configured and continue")
    			End If
    		'End If
    	End Sub
    	
    	
    	'Sub-functions to send CAN Messages to the sensor, which takes some time and in the meantime, the picture box should blink
    	Sub FSG()
    		Comm.Preoperational(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    		Comm.NodeID_ConfigurationFSGMTS(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29", tbSNFSG.Text)
    		Comm.Global_LSSDeactivate(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    		Comm.TransmitSafetyCRC(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29")
    	End Sub
    	
    	'Sub function to Blink the sensor in UI according to state of Blink variable from timerforall
    	Sub FSGBlink()
    		If Blink Then
    			pbFSG.Image = iLFSG.Images(1)
    		Else 
    			pbFSG.Image = iLFSG.Images(0)
    		End If
    	End Sub
    	
    	'Timer to change the state of Blink
    	Sub TimerforallTick(sender As Object, e As EventArgs)
    		Blink = Not Blink
    	End Sub
    Since I need to work with many Sensors/PictureBox, I cannot have a separate timer for each PictureBox to blink, that is why I have used one timer "timerforall" to change the state of the "Blink" variable, which basically later changes the image in the PictureBox after starting the timer(Which does not work, the image in the picturebox changes only once, it doesnot keep changing according to "Blink" variable).
    I also have declared the picturebox with 'WithEvents' command as suggested. Sending CAN messages part to the Sensor is working fine as expected. But the picturebox is not blinking(keep changing image in it) and I am not sure why am I having this problem?

    Any help would be highly appreciated.

    Best regards
    Krishna

  9. #9
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    10,122

    Re: How to handle two or more sub routines at a time

    I have worked extensively with Cognex sensors as well as with various PLCs (mainly Seimens) and the guy who I did work for had a very similar coding pattern to what you're trying to do.

    What I had pointed out to him was that the libraries for the vendors we were working with provided a "ResultsChanged" event. So what I ultimately did was refactor the code so that it:
    1. Make the request
    2. Start the timer to make the PictureBox controls "blink"
    3. Monitor the ResultsChanged event and stop the timer once it is fired


    Is this sort of the same thing that you are ultimately looking to do?

  10. #10
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,940

    Re: How to handle two or more sub routines at a time

    The issue you appear to be having with the current code is that you only call FSGBlink one time, so the PB only changes the one time the method is called. You need that GSGBlink code in the timer event....sort of. However, first off, what DDay mentioned supersedes anything I'm saying here, as that's the way to go if it applies to you. Still, you did say you want to work with many PB and just one timer. You are certainly correct to have just one timer. People sometimes go for one timer per control, in this case, and that's a bad thing to do. You never need more than one timer, but your situation will be a bit more complicated.

    My first thought is that I'd be inclined to have one Boolean variable per sensor, and that Boolean variable would be at form scope. The variable might be named something like sensor1Blink, sensor2Blink, etc. Then, for each sensor, you might have a method very similar to your FSGBlink method, except it would look like this:
    Code:
    Sub FSGBlink()
          If sensor1Blink Then
    		If Blink Then
    			pbFSG.Image = iLFSG.Images(1)
    		Else 
    			pbFSG.Image = iLFSG.Images(0)
    		End If
       End If
       If sensor2Blink Then
                    If Blink Then
    			pbFSG.Image = iLFSG.Images(1)
    		Else 
    			pbFSG.Image = iLFSG.Images(0)
    		End If
        End If
    'etc... One block for every sensor
    End Sub
    Then your timer tick event could look like this:
    Code:
    Sub TimerforallTick(sender As Object, e As EventArgs)
      Blink = Not Blink
      FSGBlink()
    End Sub
    The idea is that every time the timer ticks, it will blink any sensor for which the sensorXBlink Boolean is True, and not blink for any sensor for which the Boolean is false. You could expand on that idea in a variety of ways. For one thing, the timer could tick all the time, as you could just set the Booleans all to false and none would blink, but that would be a very slight waste of time.
    My usual boring signature: Nothing

  11. #11

    Thread Starter
    Junior Member
    Join Date
    Mar 2021
    Posts
    21

    Re: How to handle two or more sub routines at a time

    Quote Originally Posted by Shaggy Hiker View Post
    The issue you appear to be having with the current code is that you only call FSGBlink one time, so the PB only changes the one time the method is called. You need that GSGBlink code in the timer event....sort of. However, first off, what DDay mentioned supersedes anything I'm saying here, as that's the way to go if it applies to you. Still, you did say you want to work with many PB and just one timer. You are certainly correct to have just one timer. People sometimes go for one timer per control, in this case, and that's a bad thing to do. You never need more than one timer, but your situation will be a bit more complicated.

    My first thought is that I'd be inclined to have one Boolean variable per sensor, and that Boolean variable would be at form scope. The variable might be named something like sensor1Blink, sensor2Blink, etc. Then, for each sensor, you might have a method very similar to your FSGBlink method, except it would look like this:
    Code:
    Sub FSGBlink()
          If sensor1Blink Then
    		If Blink Then
    			pbFSG.Image = iLFSG.Images(1)
    		Else 
    			pbFSG.Image = iLFSG.Images(0)
    		End If
       End If
       If sensor2Blink Then
                    If Blink Then
    			pbFSG.Image = iLFSG.Images(1)
    		Else 
    			pbFSG.Image = iLFSG.Images(0)
    		End If
        End If
    'etc... One block for every sensor
    End Sub
    Then your timer tick event could look like this:
    Code:
    Sub TimerforallTick(sender As Object, e As EventArgs)
      Blink = Not Blink
      FSGBlink()
    End Sub
    The idea is that every time the timer ticks, it will blink any sensor for which the sensorXBlink Boolean is True, and not blink for any sensor for which the Boolean is false. You could expand on that idea in a variety of ways. For one thing, the timer could tick all the time, as you could just set the Booleans all to false and none would blink, but that would be a very slight waste of time.

    Hello,

    I have made the changes as you suggested. But still, my PictureBox is not blinking, the program directly goes to the next line and sends the messages. And when it finished sending all the messages then only the PB starts blinking. Both the tasks are not running concurrently. What could be the problem?
    Code:
    	'Clickevent of picturebox of the sensor to be configured
    	Sub FSGClick(sender As Object, e As EventArgs) Handles pbFSG.Click
    		If Access = True Then
    			If (MessageBox.Show("Configure Tilt Sensor?", "Tilt Sensor Configuration", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes) Then
    				BlinkFSG = True
                                    'timerforall.start()
    				'Thread3 = New Thread(AddressOf FSG) 'Thread with address of sub function to send CAN messages which take some time 
    				'Thread3.Start()				'start the thread
    				
                                    'Subfunctions from another Class(Comm) to send messages
    				Comm.Preoperational(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    				Comm.NodeID_ConfigurationFSGMTS(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29", tbSNFSG.Text)
    				Comm.Global_LSSDeactivate(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    				Comm.TransmitSafetyCRC(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29")
    				BlinkFSG = False	
    				
    			Else 
    				MessageBox.Show("Please select the Sensor and continue", "Select Sensor", MessageBoxButtons.OK, MessageBoxIcon.Information)
    			End If
    		End If
    	End Sub
    Code:
    	'Sub-function to call while using thread
    	Sub FSG()
    		Comm.Preoperational(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    		Comm.NodeID_ConfigurationFSGMTS(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29", tbSNFSG.Text)
    		Comm.Global_LSSDeactivate(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    		Comm.TransmitSafetyCRC(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29")
    	End Sub
    Code:
    	'Timer to change the state of Blink and call BlinkSensor function
    	Sub TimerforallTick(sender As Object, e As EventArgs)
    		Blink = Not Blink
    		BlinkSensor()
    	End Sub
    Code:
    	'Sub function to Blink the sensors in UI according to state of Blink variable from timerforall
    	Sub BlinkSensor()
    		If BlinkFSG then
    			If Blink Then
    				pbFSG.Image = iLFSG.Images(1)
    			Else 
    				pbFSG.Image = iLFSG.Images(0)
    			End If
    		End If 
    		
    		If BlinkTWK Then
    			If Blink Then
    				pbTWK.Image = iLTWK.Images(1)
    			Else 
    				pbTWK.Image = iLTWK.Images(0)
    			End If
    		End If
    		
    		If BlinkAB1 Then
    			If Blink Then
    				pbAB1.Image = iLAB1.Images(1)
    			Else 
    				pbAB1.Image = iLAB1.Images(0)
    			End If
    		End If
    End Sub

    I tried both the ways, with and without thread. But the problem is always there.
    The PictureBox blinks only if there are no other lines of code in there.
    Thanks and looking forward to your reply.

  12. #12
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,940

    Re: How to handle two or more sub routines at a time

    No other lines of code in where? I'm not sure what you are referring to, here, so there isn't much more to say. A breakpoint and some code stepping might show you what is going on, but where you put that depends on what you mean by that "no other lines of code in there" line.

    You don't need the thread, so that's not an issue. A thread will do nothing for you at all, in this case, and will eventually cause you trouble, so you can dispense with that, for now.

    One other question: What's the interval on the timer?
    My usual boring signature: Nothing

  13. #13

    Thread Starter
    Junior Member
    Join Date
    Mar 2021
    Posts
    21

    Re: How to handle two or more sub routines at a time

    Quote Originally Posted by Shaggy Hiker View Post
    No other lines of code in where? I'm not sure what you are referring to, here, so there isn't much more to say. A breakpoint and some code stepping might show you what is going on, but where you put that depends on what you mean by that "no other lines of code in there" line.

    You don't need the thread, so that's not an issue. A thread will do nothing for you at all, in this case, and will eventually cause you trouble, so you can dispense with that, for now.

    One other question: What's the interval on the timer?
    Hello,

    I am also not sure why is this code not working as expected. I also did debugging and as I said the program enters in the Subfunction and executes each line, It sends the Messages but the PB does not blink.

    But It works fine if there are no other lines of code in clickevent of PB. I mean the following code works fine.
    Code:
    	'Clickevent of picturebox of the sensor to be configured
    	Sub FSGClick(sender As Object, e As EventArgs) Handles pbFSG.Click
    		If Access = True Then
    			If (MessageBox.Show("Configure Tilt Sensor?", "Tilt Sensor Configuration", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes) Then
    				BlinkFSG = True	
    				
    			Else 
    				MessageBox.Show("Please select the Sensor and continue", "Select Sensor", MessageBoxButtons.OK, MessageBoxIcon.Information)
    			End If
    		End If
    	End Sub
    But after adding the other lines of code as in clickevent of the previous post, PB does not blink.

    The Interval of the timer is 1 sec. Does this cause any problem?
    Looking forward to your response.

  14. #14
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,290

    Re: How to handle two or more sub routines at a time

    In the previous case, you set BlinkFSG = True, and then you set it to False.
    In this code, you don't set it to False.
    So in the previous code when the timer fires, BlinkFSG will be False and not blink since the timer can't fire until you leave the subroutine.

    If the comms takes enough time that the picturebox should be blinking while the comm is going on, then put the comm code in a task that runs in the background, so that the click event sub is exited and the timer events can be processed to blink the picturebox.
    I guess you'll then need to know then the comm is done to stop the blinking. I guess you would check for that in the timer.
    Or more than likely, do what DDay suggests in post #9 to make it more event driven.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  15. #15
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,940

    Re: How to handle two or more sub routines at a time

    I second what passel just said. The blink part doesn't make sense in a thread, but this part:

    Code:
    Comm.Preoperational(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    Comm.NodeID_ConfigurationFSGMTS(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29", tbSNFSG.Text)
    Comm.Global_LSSDeactivate(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    Comm.TransmitSafetyCRC(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29")
    is very much suitable for a thread, or a Task. Blinking requires the UI thread to be free. If the UI thread is free, then it will be able to process events as they get raised. The significant events that are getting raised, in this case, are the tick event and the picturebox Paint event. So, the UI thread must be free to process events, which is what it does when it isn't busy running any code. If those lines take any significant amount of time, they will block the UI thread, because they are running on the UI thread. Keep in mind that events won't interrupt anything else that the thread is doing. The event will wait until nothing else is going on.
    My usual boring signature: Nothing

  16. #16

    Thread Starter
    Junior Member
    Join Date
    Mar 2021
    Posts
    21

    Re: How to handle two or more sub routines at a time

    Hello Everyone,

    I have succeeded to make my program run for each click event of the PictureBox, all because of your help, thanks to everyone.

    But now I am having a problem to run my program for Automatic mode i,e User no more selects the PictureBox but the program Itself by using a loop. Starting from the First sensor to many according to the number of sensors installed in the machine. I have tried to use the same idea as in Manual mode but it's not working.

    The working code from Manual Mode is:
    Code:
    	'Clickevent of picturebox of the sensor to be configured
    	 Sub FSGClick(sender As Object, e As EventArgs) Handles pbFSG.Click
    		If Access = True Then
    			If (MessageBox.Show("Configure Tilt Sensor?", "Tilt Sensor Configuration", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes) Then
    				BlinkFSG = True
    				Thread3 = New Thread(AddressOf FSG) 'Thread with address of sub function to send CAN messages
    				Thread3.Start()
    				
    			Else 
    				MessageBox.Show("Please select the Sensor and continue", "Select Sensor", MessageBoxButtons.OK, MessageBoxIcon.Information)
    			End If
    		End If
    	End Sub
    		
    	
    	'Sub-functions to send CAN Messages to the sensor
    	Sub FSG()
    		Comm.Preoperational(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    		Comm.NodeID_ConfigurationFSGMTS(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29", tbSNFSG.Text)
    		Comm.Global_LSSDeactivate(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    		'Comm.TransmitSafetyCRC(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "FSG", "29")
    		
    		If (MessageBox.Show("Configuration of Tilt sensor completed, Do you want to configure Other sensor?", "Tilt Sensor Configuration", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes)Then
    			BlinkFSG = False
    			pbFSG.Image = iLFSG.Images(1)
    			
    		Else
    			If (MessageBox.Show("Are you sure you want to quit the application?", "Quit Application", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes)Then
    				Application.Exit()
    			Else
    				'Thread3.Abort()
    			End If
    		End If
    		
    	End Sub
    The above code works fine. It Communicates with the Sensor as well as blinks the Picturebox of the selected Sensor.

    But in the Automatic Mode, it should run automatically. How am I supposed to use Threads with loop? What I have tried is:
    Code:
    If (MessageBox.Show("Start configuring Support Sensors?", " Sensor Configuration", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes) Then
    					cbSelectMode.Enabled = False				'Disable Select Mode options after selecting and confirming one
    					Dim k As Integer = 0
    					Dim NodeIDsAB() As String = {"2B","2C","0D","0E"}	
    					Dim AllSerialNumbersAB() As String = {tbSNAB1.Text, tbSNAB2.Text, tbSNAB3.Text, tbSNAB4.Text} 
    					
    					'Dim j As Integer = 0
    					'Make respective picturebox blink and send CAN message for the Configuration
    					
    					
    					For k=0 To 3						
    						'BlinkAB1 = True
    						'Dim ArmThreadBlink As Thread = New Thread(DirectCast(Sub() PickNecessaryParameters1(k), ThreadStart))
    						'ArmThreadBlink.Start()
    						
    						Dim ARMThreadBlink As Thread = New Thread(AddressOf BlinkABSensors)
    						Dim Parameters = New Object(){NodeIDsAB(k),AllSerialNumbersAB(k),k}
    						
    						ARMThreadBlink.Start(Parameters)
    						
    						
    						'Comm.Preoperational(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    						'Comm.NodeID_ConfigurationFSGMTS(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "MTS", NodeIDsAB(k),AllSerialNumbersAB(k))
    						'Comm.Global_LSSDeactivate(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    						'Comm.TransmitSafetyCRC(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "MTS", NodeIDsAB(k))
    						
    					Next
    					BlinkAB4 = False
    										
    				Else 
    					MessageBox.Show("Please select the Mode and continue", "Select Mode", MessageBoxButtons.OK, MessageBoxIcon.Information)
    					cbSelectMode.Focus()
    					
    				End If
    				Sub BlinkABSensors(Parameters As Object)
    					PickNecessaryParameters(Parameters(0), Parameters(1), Parameters(2))
    				End Sub
    				
    				
    				Sub PickNecessaryParameters(ByVal NodeID As String, ByVal SerialNumber As String, Byval k As Integer)
    					Select Case k
    									
    								Case 0
    									BlinkAB1 = True
    									
    								Case 1
    									BlinkAB1 = False
    									BlinkAB2 = True
    									
    								Case 2
    									BlinkAB2 = False
    									BlinkAB3 = True
    									
    								Case 3
    									BlinkAB3 = False
    									BlinkAB4 = True
    					End Select
    					
    					Comm.Preoperational(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    					Comm.NodeID_ConfigurationFSGMTS(PcanDevice.Usb, ClientHandle, CurrentNetHandle, "MTS", NodeID,SerialNumber)
    					Comm.Global_LSSDeactivate(PcanDevice.Usb, ClientHandle, CurrentNetHandle)
    
    				End Sub
    Also, the Messages to the Sensors are sending all at a time. Messages are supposed to send one by one according to the loop value but this program is sending all four messages(These messages are defined in comm class) at once.
    The timer function is the same as earlier.

    I hope my requirement is clear and any help would be highly appreciated.

    Best regards
    Krishna

  17. #17
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,940

    Re: How to handle two or more sub routines at a time

    In theory, you could have multiple threads, one for each sensor. In practice, that is probably a bad idea. The reason I think it would be bad is that threads aren't magic. They take time on the CPU. These days, almost every CPU will have multiple cores, so you could (in theory, though perhaps not in practice) have one thread per core without them stepping on each other. However, once you have more threads than you have cores, they will certainly step on each other, and they may do so even if you have fewer threads than cores, due to things like thread affinity.

    If the threads step on each other, that might not be a bad thing, depending on how it happens. If all threads are running, then they will split time on the CPU. This could result in everything blinking, but doing so in erratic fashion as each thread got to use the CPU for a time, then yielded to the next thread, and so forth. Every switch from one thread to the next would come at a slight cost, as well, which can cause multi-threading programs to sometimes run slower than single threaded programs, depending on much much switching has to take place. That probably wouldn't matter at all to you, though, because you aren't threading to speed everything up. However, the other option is that the threads get pooled, in which case one thread might not run at all while the others are running, which would result in some blinking and others not blinking, perhaps forever. That certainly wouldn't be what you wanted.

    For this reason, I don't think multiple threads is necessarily what you want. It may not be an easy decision, either. One alternative would be to use just one thread. In that one thread, you would interact with each sensor in turn. Whether or not that would be suitable depends on how long it takes to interact with any one sensor. If the interaction with sensor A takes 2 ms, the interaction with sensor B takes 40 ms, and the interaction with sensor C takes 5 ms, then if you went in the order A, B, C, and kept repeating that loop, no sensor would be accessed more often than once every 47 ms. If the times were longer or shorter, the rate at which each could be interacted with would also get longer or shorter. Is that okay? If so, then having the thread deal with each one in sequence might be a good solution.

    If the time to interact with all the sensors is too long, then some other solution has to be arrived at, and that will get tricky. Fortunately, if interacting with one sensor takes longer than a millisecond, then threads will not step on one another very often. They'll be spending most of their time waiting for the sensor to respond. A millisecond is a long time in computer terms. Any waiting is a good thing. The more waiting you have, the more time can be devoted to other threads, so if all sensors are waiting for some length of time, then all the threads will be spending more time waiting, so you can have more threads running simultaneously without hogging time from other threads.

    So, perhaps the key question is: Are the sensor interactions super fast, or noticeably slow?
    My usual boring signature: Nothing

  18. #18
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,290

    Re: How to handle two or more sub routines at a time

    Since each sensor case stops the blinking of the previous case, it seems like you really want these to occur in a series one after the other. The next one shouldn't start until the previous one is done.

    In which case, rather than loop in the GUI thread and kick off each sensor communication in its own thread so that they run at the same time in parallel, you should just kick off one background thread and have it loop through each of the sensors so they run serially in that thread, while your Gui can status the progress by blinking the pictureboxes from its timer event.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  19. #19

    Thread Starter
    Junior Member
    Join Date
    Mar 2021
    Posts
    21

    Re: How to handle two or more sub routines at a time

    Quote Originally Posted by passel View Post
    Since each sensor case stops the blinking of the previous case, it seems like you really want these to occur in a series one after the other. The next one shouldn't start until the previous one is done.

    In which case, rather than loop in the GUI thread and kick off each sensor communication in its own thread so that they run at the same time in parallel, you should just kick off one background thread and have it loop through each of the sensors so they run serially in that thread, while your Gui can status the progress by blinking the pictureboxes from its timer event.
    Hello passel,

    Yes, this is exactly what I am trying to do but unfortunately not succeeded yet. I am not sure how am I supposed to implement this idea. Could you please help me further by looking into the code in my previous post. How am I supposed to modify that code?

  20. #20

    Thread Starter
    Junior Member
    Join Date
    Mar 2021
    Posts
    21

    Re: How to handle two or more sub routines at a time

    Quote Originally Posted by Shaggy Hiker View Post
    In theory, you could have multiple threads, one for each sensor. In practice, that is probably a bad idea. The reason I think it would be bad is that threads aren't magic. They take time on the CPU. These days, almost every CPU will have multiple cores, so you could (in theory, though perhaps not in practice) have one thread per core without them stepping on each other. However, once you have more threads than you have cores, they will certainly step on each other, and they may do so even if you have fewer threads than cores, due to things like thread affinity.

    If the threads step on each other, that might not be a bad thing, depending on how it happens. If all threads are running, then they will split time on the CPU. This could result in everything blinking, but doing so in erratic fashion as each thread got to use the CPU for a time, then yielded to the next thread, and so forth. Every switch from one thread to the next would come at a slight cost, as well, which can cause multi-threading programs to sometimes run slower than single threaded programs, depending on much much switching has to take place. That probably wouldn't matter at all to you, though, because you aren't threading to speed everything up. However, the other option is that the threads get pooled, in which case one thread might not run at all while the others are running, which would result in some blinking and others not blinking, perhaps forever. That certainly wouldn't be what you wanted.

    For this reason, I don't think multiple threads is necessarily what you want. It may not be an easy decision, either. One alternative would be to use just one thread. In that one thread, you would interact with each sensor in turn. Whether or not that would be suitable depends on how long it takes to interact with any one sensor. If the interaction with sensor A takes 2 ms, the interaction with sensor B takes 40 ms, and the interaction with sensor C takes 5 ms, then if you went in the order A, B, C, and kept repeating that loop, no sensor would be accessed more often than once every 47 ms. If the times were longer or shorter, the rate at which each could be interacted with would also get longer or shorter. Is that okay? If so, then having the thread deal with each one in sequence might be a good solution.

    If the time to interact with all the sensors is too long, then some other solution has to be arrived at, and that will get tricky. Fortunately, if interacting with one sensor takes longer than a millisecond, then threads will not step on one another very often. They'll be spending most of their time waiting for the sensor to respond. A millisecond is a long time in computer terms. Any waiting is a good thing. The more waiting you have, the more time can be devoted to other threads, so if all sensors are waiting for some length of time, then all the threads will be spending more time waiting, so you can have more threads running simultaneously without hogging time from other threads.

    So, perhaps the key question is: Are the sensor interactions super fast, or noticeably slow?
    Hello,

    It takes around 30-40 Sec to make the complete communication to each sensor. And in the meantime, the respective sensor PictureBox should blink. That's what I am trying to do. Can you please help me to modify my above code so that it works according to my requirement. Any help would be highly appreciated.

  21. #21

    Thread Starter
    Junior Member
    Join Date
    Mar 2021
    Posts
    21

    Re: How to handle two or more sub routines at a time

    Hello everyone,

    The code has now worked. Both the task (Communication and blinking) is running as needed.
    Many thanks to you all. I appreciate your effort and time.

  22. #22
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,940

    Re: How to handle two or more sub routines at a time

    Please mark the thread Resolved (on the Thread Tools). Feel free to start a new thread if you have a new question, as well.
    My usual boring signature: Nothing

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