2014-05-19 29 views
7

Ho bisogno di eseguire molti script da riga di comando. Attualmente sono memorizzati in un List. Voglio eseguirli tutti allo stesso tempo e procedere con il passaggio successivo solo dopo che tutti sono stati completati.Attendere fino al completamento di più processi da riga di comando?

Ho provato l'approccio che mostro di seguito, ma l'ho trovato mancante perché l'ultimo comando non è necessariamente fine fine. Infatti, ho trovato che l'ultimo comando può anche essere il primo da completare. Quindi, credo di aver bisogno di qualcosa come WaitForExit(), ma che non ritorna fino al tutti i processi di esecuzione sono stati completati.

for (int i = 0; i < commands.Count; i++) 
{ 
    string strCmdText = commands[i]; 
    var process = System.Diagnostics.Process.Start("CMD.exe", strCmdText); 
    if (i == (commands.Count - 1)) 
    { 
     process.WaitForExit(); 
    } 
} 
//next course of action once all the above is done 

risposta

7

Dato che ogni chiamata a Process.Start avvia un nuovo processo, è possibile tutti tenere traccia separatamente, in questo modo:

var processes = new List<Process>(); 
for (int i = 0; i < commands.Count; i++) 
{ 
    string strCmdText = commands[i]; 
    processes.Add(System.Diagnostics.Process.Start("CMD.exe", strCmdText)); 
} 

foreach(var process in processes) 
{ 
    process.WaitForExit(); 
    process.Close(); 
} 

EDIT

Process.Close() aggiunto come nei commenti

+1

Trovo questa soluzione meglio di qualsiasi approccio parallelo compito offerto, dal momento che non usa inutilmente/creare ulteriori discussioni – Edin

+0

E 'necessario chiamare process.close()? http://msdn.microsoft.com/en-us/library/fb4aw7b8%28v=vs.110%29.aspx –

+1

Probabilmente non strettamente necessario, poiché 'Process' eredita un finalizzatore da' Component', ma è buona pratica smaltire presto. In questo esempio è anche abbastanza facile (basta chiamare 'Close()' dopo 'WaitForExit()' in ogni ciclo iterativo). –

5

Utilizzare una matrice di attività e attendere che tutte le operazioni vengano completate.

var tasks = new Task[commands.Count]; 
for (int i = 0; i < commands.Count; i++) 
{ 
    tasks[i] = Task.Factory.StartNew(() => { 
     string strCmdText = commands[i]; 
     var process = System.Diagnostics.Process.Start("CMD.exe", strCmdText); 
     process.WaitForExit(); 
    }); 
} 

Task.WaitAll(tasks); 

O, più LINQ ishly come questo:

var tasks = commands.Select(strCmdText => Task.Factory.StartNew(() => { 
    var process = System.Diagnostics.Process.Start("CMD.exe", strCmdText); 
    process.WaitForExit(); 
})).ToArray(); 
Task.WaitAll(tasks);