2014-05-19 19 views
7

Mam potrzebę wykonywania wielu skryptów wiersza poleceń. Obecnie są przechowywane w postaci List. Chcę uruchomić je wszystkie w tym samym czasie i przejść do następnego kroku po zakończeniu ich wszystkich.Poczekaj na zakończenie wielu procesów wiersza poleceń?

Próbowałem podejście, które przedstawię poniżej, ale znalazłem go brakuje, ponieważ ostatnie polecenie niekoniecznie koniec ostatni. W rzeczywistości okazało się, że ostatnie polecenie może być nawet najpierw do ukończenia. Tak więc uważam, że potrzebuję czegoś takiego jak WaitForExit(), ale która nie powróci, dopóki nie zakończy się wykonywanie procesów.

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 

Odpowiedz

7

Ponieważ każde wywołanie Process.Start rozpoczyna się nowy proces, można śledzić ich wszystkich z osobna, tak jak poniżej:

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() dodawane jako w komentarzach

+1

Uważam to rozwiązanie lepsze niż oferowane zadań równoległym podejściu, ponieważ nie niepotrzebnie używać/tworzyć kolejne wątki – Edin

+0

Czy trzeba zadzwonić process.Close()? http://msdn.microsoft.com/en-us/library/fb4aw7b8%28v=vs.110%29.aspx –

+1

Prawdopodobnie nie jest to absolutnie konieczne, ponieważ "Proces" dziedziczy finalizator z "Komponentu", ale dobrą praktyką jest rozporządzać wcześniej. W tym przykładzie jest to również łatwe (po prostu wywołaj 'Close()' po 'WaitForExit()' w każdej iteracji pętli). –

5

Użyj tablicy zadań i poczekaj, aż wszystkie zostaną ukończone.

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); 

Albo, bardziej LINQ-ishly tak:

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