Solved

How to execute multiple tasks sequentially

Posted on 2011-09-24
17
558 Views
Last Modified: 2012-05-12
Hi experts,

I am new to .net programming and I am having difficulty with one area.  I wrote (90% complete) a program which will allow me to quickly configure a hard drive once imaged.  The program opens up into a multi-tabbed form.  One of the tabs have fields for computer name, individual fields for putting in the IP, SNM, DGW etc.  I want my tech's to have the ability start the program, open the tab, fill out the appropriate fields then either apply all the settings with a single click of a button or just apply the settings for one of the separate sections ie: either computer name or IP Address only.  I am using visual Studios 2010.

Initially, I created sub routines for each task (change computer name, change IP address, etc).  I can execute each individual task (change computer name or change IP address) individually when i click the button to change the one section.   The issue is coding the config all button.  When this button is clicked, I want the program to start by executing the "change_computer_name" subroutine while all the other subroutines are waiting in queue.  Once the "change_computer_name"  subroutine is completed, the "change_IP_Add" subroutine launches.  

My research has lead me down the path of using a "BackgroundWorker" or using "Queuing" for this feature.  I have spent at least a full day (24 hours cumulative) exploring these possibilities however I cannot seem to get it done.  I pride myself on being able to self study and get it done but it’s time to swallow my pride and ask.

Any assistance would be appreciated.

V/R

Izzy
Load-Configurator-tab.jpg
0
Comment
Question by:israelanta
  • 8
  • 5
  • 3
  • +1
17 Comments
 
LVL 4

Expert Comment

by:Ambusy
ID: 36592979
proceed on the path for one entry, where you call all routines for that entry.
On the ALL click, call the routines for each of the entries one after the other.

A backgroundworker would be used by me INSIDE each of the small routines: while the process of configuring something is going on, the techician may continue in the meantime on the desktop inserting date for the next operation. With the routine in foreground he has to wait until the ruotine has finished to continue his work. When the ALL part starts, I guess there is no more a need to keep the keyboard unlocked. He has to wait anyway until all has finished.
0
 
LVL 40
ID: 36592993
The background worker is not the right thing to use, it will make all the jobs being executed in parallel, which is the contrary of what you want to do.

Queuing is the right thing, but you do not need to do it, it will be done automatically for you. .NET always terminate an event before going to the following one. So if the user press on 3 buttons in a row, the Click for the second button will be held back until the Click of the first one has executed. And then, the Click event of the third button will wait until the second Click has finished processing.

So, basically, you have nothing to do, it will be done for you.

You can check that by putting a MessageBox at the start and end of each of the Click events. You will see that they execute in sequence.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 36594453
...except that, without using a backgroundworker (or manual threads), the main UI will lock up and freeze while the tasks are being done.

Move the code out of each button and into their own methods; then make each button call its respective method.

Now, in your backgroundworker, you can just call each method sequentially.
0
 
LVL 40
ID: 36595266
If the user has filled all the fields before clicking on the buttons, the main UI lock up won't be important. The clicks on the button will record anyway. A click just won't be processed until the previous one has finished.

If each button calls its respective method, "Now, in your backgroundworker, you can call each method sequentially" will be useless since the methods will have already been called on the click.

Since the jobs need to be done in sequence, using threads would completely break the requirement, since the role of threads is the opposite, processing in parallel. And in case of anything that has to do with the hard disk, threads are just a way to break performance, because the disk keeps having to move its heads continually because the system keeps switching between threads. Besides, that might well be the reason behind the need to process in sequence. It makes things faster.

I think that the best way to really execute in sequence without freezing the interface would be for the clicks to send a message to a queue and process the queue. That is more involved, and that is why I did not suggest it in the first place.

The way to go depends on the way you want the users to interact with the form.
0
 

Author Comment

by:israelanta
ID: 36595320
Ambusy, you are correct.  I didn't realize it because i wasn't trying to move or do anything else with my main UI but it does in face freeze.  I will have to do a background worker to stop that from happening.  Now back to the issue of how to create.  I will go back to Google and MSDN unless you have something pre done to throw this way.  I don't like asking but time is on my back.

JamesBurger: I tested the program and found out that what you said about .net queuing automatically is half true in the way i created the program.  for example: in the picture above  I created a sub routine for change computer name, change ip address, Microsoft loopback adapter and adding a comport number to the one mapping program we use. Each of these subs only go into the registry and do simple delete, add or change reg keys or in the case of the loopback adapter i am using wmi.  When i press the configure hard drive button, i call each of these subs in order ie:
computername()
configIP()
configLBA()
AddGPSCOMPORT()
Restart()
In this button, the program does in fact wait for one to finish before starting another.

on the next tab of the program, I have a button to clean up the hard drive.  I want this button to execute a series of steps in order as well.  As before, I created a sub routine for each step.  the steps are as follows: delete recent items list, conduct a disk cleanup, clear event logs, defrag c:, defrag d, then show dialog box asking if I wan to shut down now or wait, if Yes is pressed, the computer shuts down.
The difference in these sub routines are that in these subs I am starting processes.  
Step 1 - delete recent Items: Reg key deletes and creates - this is fast and works fine.  program waits then goes on to next step.
Step 2- clear event logs:  this is a wmi script and works fine.  Program executes then goes on to next step.
Step 3-disk cleanup:  Here i am starting a process, this is where it starts running them at the same time.  It seems that when the process begins, VB is going on to the next step.  I also created a sub for this one:        System.Diagnostics.Process.Start("cleanmgr.exe", "/sagerun:1")

Step 4 and Step 5 are similar to above with the same results, when the process starts the program goes on.  
Step 4 is:  System.Diagnostics.Process.Start("defrag.exe", "c: -f")
Step 5 is:  System.Diagnostics.Process.Start("defrag.exe", "d: -f")
Step 6: Msg box works fine.
Note:  I even tried starting the process in the same button click routine using a .waitforexit .  I dimmed the process then called the process as follows:
dim diskcleanup as process = System.Diagnostics.Process.Start("cleanmgr.exe", "/sagerun:1")
and did the same for defrag C and D.
diskcleanup.waitforexit()
defragC.waitforexit()
defragD.waitforexit()
also tried "WaitForInputIdle".  these did not work as well.  This is the reason i think I need to add queuing.

Having rambled enough, if anyone agrees that I need to introduce queuing into the code to have these subs wait can you provide examples of queuing to launch subs or process sequentially.

Thanks again in advance.
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 400 total points
ID: 36595355
WaitForExit() will work but you need to use them in the right order:

    Dim P As Process = Process.Start("A.exe")
    P.WaitForExit()
    P = Process.Start("B.exe")
    P.WaitForExit()

In the above snippet, "B" will not start until "A" has completed.

If you run this code from a Button handler, though, then your main UI will freeze until all the processes complete.  This does make a difference if the processes are long as your application will experience a "white out" which is the inability to paint itself because the main UI thread is waiting for the processes to exit.  This is why you do need a different thread or a backgroundworker to spawn the processes and wait for them!
0
 

Author Comment

by:israelanta
ID: 36595381
Idle Mind:

Do I do what you suggested in the subroutines I created or bring them back into the button_click event.  

right now I have a sub for each of those process, do I re-write the subs for each as indicated by  you above.  If I re-write the subs, then when I call them in the button_click event, do I use the WaitForExit ie: call cleanup.WaitForExit  or just call the sub normally  ie: call cleanup.  

Sorry in advance if this is a dumb question or if mixing up terminology, not school trained.
0
 

Author Comment

by:israelanta
ID: 36595384
Idle Mind:

Sorry, I misread your post.  I will try and post back with results
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:israelanta
ID: 36595400
Idle Mind:

Re-writing the process as indicated above worked for getting the tasks to run sequentially.  Now just waiting on some help from someone as to the background worker and how to implement in my senario.

Thanks,

1 of 2 down.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 36595414
Great!

Now for the good news and bad news.

Good News:  If you've already moved each subroutine into its own method then writing the "Config All" routine is simply a matter of calling each method from a single BackgroundWorker.

Bad News: Achieving "sequential" execution when the user manually clicks the different buttons is a bit trickier.  For that, as James mentioned, you'd need some kind of queuing system.  One way to do that would be to use a "master" BackgroundWorker() that pulls items from the queue and runs them.  As each button is clicked, that task would be added to the queue.

I'll post a simple queuing system later if no one else does.
0
 
LVL 40
ID: 36595423
When you start a process, it starts on its own thread and your Click finishes, going to the following finish while the process is running in parallel. That is why System.Diagnostics.Process.Start("cleanmgr.exe", "/sagerun:1") does not work well in that scenario. That is also why I said from the start that working with threads or a Backgroundwork (that is only a simple way to work with threads) would not work.

I was not aware that you were calling external programs. In such case the best alternatives are the WaitForExit (easy to program but will freeze the application until all the jobs are finished) or a queue (a little more processing, but you get full control, such as the possibility to cancel between operations if desired).

Once again, I personnally do not think, the BackgroundWorker is not a good solution. You would need to have a queue anyway to accumulate the jobs, and as soon as you incorporate multithread in an application, you are bringing in synchronization issues. Starting a new thread (through Process.Start) inside of another one (the BackgroundWorker), inside of another one (your Form) could work on the first time if you are lucky, but you run the risk of falling into a very uninteresting debugging scenario. Not counting that there are special issues with threads and Process.Start. Give a look at the last paragraph before the examples of the Visual Studio 2010 documentation for Process.Start (string)

A simple Timer working with a queue would be, in my humble opinion, a lot safer as far as your own time is concerned.
0
 

Author Comment

by:israelanta
ID: 36595738
idle Mind

the good news is that in my program, while the potential is there for one of my techs to click the individual config buttons one at a time in rapid success, i doubt any of them will.  For that reason i think your solution for just creating the backgroundworker for the config all button would finish the program.  again, an example would be nice.

JamesBurger:

I am all for setting this program the best way, again, i am extremely new to this thus if you had a simple example i will try.  You menttion the Visual studio 2010 documentation, I will review once i find the section.  I will also review your last suggestion, again, an example would be nice.
0
 
LVL 40
ID: 36595789
I am very busy today and tomorrow, I do not have the time to build and test an example. Will try to do that on Tuesday toward the end of the afternoon if I can find time.
0
 

Author Comment

by:israelanta
ID: 36595811
James


No problem, you have been great and I truely appreciate your advise.  I will continue to research your last suggestion.

Thanks again

Izzy
0
 
LVL 40

Assisted Solution

by:Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger) earned 100 total points
ID: 36599815
Needed a small break, and your thing looks like a fun challenge.

Given a Form with 3 buttons to record the operations (Button1, Button2, Button3), and one button to launch the sequence (btnGo). Also a timer (Timer1) that is our main sequencing tool.

Adapt the following to your needs:
Public Class Form1

  Dim _operationQueue As New Collections.Generic.Queue(Of Button)
  
  Private Sub Buttons_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click

    Dim caller As Button = DirectCast(sender, Button)

    _operationQueue.Enqueue(caller)    'Add the button to the queue
    caller.Enabled = False            'If needed. Prevent the user from executing the same operation twice
    btnGo.Enabled = True              'Now that we have at least one operation, we can activate Go

  End Sub

  Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick

    If _operationQueue.Count > 0 Then

      Timer1.Enabled = False  'Prevents useless firing of the timer while we are processing one operation

      Dim app As Process
      Dim operation As Button = _operationQueue.Dequeue  'Get the next Button in the queue

      Select Case True
        Case operation Is Button1
          app = Process.Start("Calc.exe")
          app.WaitForExit()    'Freeze here. The timer being disabled, the following operations will wait
        Case operation Is Button2
          app = Process.Start("Notepad.exe")
          app.WaitForExit()
        Case operation Is Button3
          app = Process.Start("C:\Program Files\Prog\Projects\JBBackup\bin\Debug\JBBackup.exe")
          app.WaitForExit()
      End Select

      Timer1.Enabled = True  'Restart the timer, which will bring us back here and process the next operation.

    End If

  End Sub

  Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load

    Timer1.Enabled = False  'We do not want the time until we are ready to go
    btnGo.Enabled = False    'No need to click on Go until an operation has been selected

  End Sub

  Private Sub btnGo_Click(sender As Object, e As System.EventArgs) Handles btnGo.Click

    Timer1.Interval = 250      'A quarter of a second delay to leave time for an operation to start. Otherwise, 2 operations could launch in the same run. Increase if you se that this happens.
    Timer1.Enabled = True      'Start the timer

  End Sub

End Class

Open in new window

Feel free to ask if you need clarifications.

Hope this will suit your need.

0
 

Author Closing Comment

by:israelanta
ID: 36896309
Sorry for the delay, i had to leave and work off site on a project.
0
 

Author Comment

by:israelanta
ID: 36896360
First of all I want to thank all of you who participated in providing solutions for this question.  I have been a member of Experts-Exchange since Jan 2006 and have always been impressed with the details provided in the solutions.  As my responsibility and workload increase, I find myself coming back to Experts-Exchange more and more.  While I have only asked 5 questions in the past 5 years, each solution was able to jump start a stalled project. As to this project, it is finished and in testing by some of my techs for proof of concept and completeness.  

As to the solutions, the original question was (How to execute multiple tasks sequentially).  Idel_Minds solution did the trick.  James, I could not get your code for creating and starting items in a queue to work but have not stopped trying.  I was pulled away for offsite support that consumed all of my time for the last few days.  Now that I am back I plan on working on the background worker or James queue to make the project complete.

Once again, thanks
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Displaying an arrayList in a listView using the default adapter is rarely the best solution. To get full control of your display data, and to be able to refresh it after editing, requires the use of a custom adapter.
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

757 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now