Managing Windows Processes in Web Service

I am currently firing off a windows process using System.Diagnostics.Process and waiting for the process to complete before allowing the code to proceed.  This is currently inefficient especially when I have 30 or 40 different process to fire off.  I wouldn't want to run all of them at once but I would be ok with running five of them at a time.  

The main requirement that I have is that I need to be able to know when all of the processes are completed.  To accomplish this currently I am using an asynchronous web service call that runs the processes.  When the web service call is completed I know that the all of the processes are finished.  

So my question is can I run more than one process at a time and at the same time, know when all of them have completed, and keep the web service call from returning a response?  If so, can you provide a simple example of how I might accomplish this.
LVL 3
kmcbreartyAsked:
Who is Participating?
 
Luis PérezConnect With a Mentor Software Architect in .NetCommented:
Ok, with this changes I think you'll be in the right way...

Hope that helps.
Dim myProcesses As List(Of Process) = New List(Of Process)

'Add your processes here...
...

Const max_processes_at_same_time As Integer = 5
Dim allExit As Boolean
Do
    'Sleep the thread 100 ms
    System.Threading.Thread.Sleep(100)
    'Check the state of all the processes
    Dim runningProcesses As Integer = 0
    Dim unstartedProcesses As Integer = 0
    Dim firstUnstarted As Process = Nothing
    allExit = True
    For Each p As Process In myProcesses
        Try
            If p.Id <> 0 Then
                'The process has started
                If Not p.HasExited Then
                    'Not all process has existed
                    allExit = False
                    'Add 1 to running processes
                    runningProcesses += 1
                End If
            End If
        Catch ex As Exception
            'The process has not started
            unstartedProcesses += 1
            If IsNothing(firstUnstarted) Then firstUnstarted = p
            allExit = False
        End Try
    Next

    'If there are unstarted processes and we can start another one, start it
    If (unstartedProcesses > 0) AndAlso (runningProcesses < max_processes_at_same_time) Then
        firstUnstarted.Start()
    End If
Loop Until allExit

Open in new window

0
 
Luis PérezSoftware Architect in .NetCommented:
I'm not sure to completely understand your question... but I'll give a try.

Is your call to the web service working ok? I mean, are you able to notify to web service caller at the moment that you want?

If so, why don't you try to instance a List of processes, launch them and periodically check if all of them have exited?

For example:
Dim myProcesses As List(Of Process) = New List(Of Process)
'Add your processes to the list
...
'Launch all the processes
For Each p As Process In myProcesses
    p.Start()
Next

'Keep on waiting until all processes has exited
Dim allExit As Boolean
Do
    'Sleep the task 100 ms
    System.Threading.Thread.Sleep(100)
    'Check if all the processes has exited
    allExit = True
    For Each p As Process In myProcesses
        If Not p.HasExited Then
            allExit = False
            Exit For
        End If
    Next
Loop Until allExit
'Once here, you know that ALL your processes has exited

Hope that helps.
0
 
kmcbreartyAuthor Commented:
Yes, my call to the web service works exactly the way I want it to.

I was thinking something along the lines of the code that you provided but I don't want to run all of them at once.  I don't want more than five process running at a time.  I like your idea of creating all of the processes before hand in a list and I didn't realize the process had a HasExited property.  That solves my initial problem with how to keep track of the processes.
0
 
kmcbreartyAuthor Commented:
I took your code and expanded on it a little bit to make it more readable and efficient.  Thank you for a great starting point.

Here is my final code:

    Public Shared Sub RunReports(ByVal Reports As IList(Of ScheduledReportSummary))
        Const MaxRunningProcess As Integer = 5
        Dim LastRanProcess As Integer

        ' Create Management Lists
        Dim ToProcess As List(Of Process) = GetProcessList(Reports)
        Dim Running As New List(Of Process)

        ' Run Reports
        Do
            'Sleep the thread 100 ms
            System.Threading.Thread.Sleep(100)
            RemoveFinishedProceses(Running)

            While Running.Count < MaxRunningProcess AndAlso LastRanProcess < ToProcess.Count
                Dim p As Process = ToProcess.Item(LastRanProcess)
                p.Start()

                Running.Add(p)
                LastRanProcess += 1
            End While
        Loop Until Running.Count = 0
    End Sub

    Private Shared Sub RemoveFinishedProceses(ByRef ProcessList As List(Of Process))
        ' Create a copy of the list to enumerate
        Dim l As List(Of Process) = ProcessList.ToList

        For Each p As Process In l
            If p.HasExited Then
                ProcessList.Remove(p)
            End If
        Next
    End Sub

Open in new window

0
All Courses

From novice to tech pro — start learning today.