2013-04-17 5 views
0

Я пытаюсь запустить несколько внешних приложений из моего приложения. Предположим, что я хочу запустить приложение LongtimeRun.exe в 10 раз, и каждый раз, когда эти приложения запускаются, для завершения требуется около 30 секунд (общее время составляет 300 секунд или 5 минут!). Я также хочу дать пользователю некоторые индикаторы выполнения (например, сколько раз приложение запускается).Выполнение процесса внутри рабочего потока (C#)

Я могу создать пакетный файл и запустить LongTimeRun.exe там 10 раз, но тогда я не могу показать отчет о ходе работы.

У меня есть этот код, который работает:

using System.Diagnostics; 
using System.IO; 

public class CommandProcessor 
{ 
     private readonly string binDirectory; 
    private readonly string workingDirectory; 
    public CommandProcessor(string workingDirectory, string binFolderName) 
    { 
     binDirectory = Path.Combine(FileSystem.ApplicationDirectory, binFolderName); 
     this.workingDirectory = workingDirectory; 
    } 
    public int RunCommand(string command, string argbase, params string[] args) 
    { 
     var commandPath = Path.Combine(binDirectory, command); 
     var formattedArgumets = string.Format(argbase, args); 

     var myProcess = new Process(); 
     myProcess.EnableRaisingEvents = false; 
     myProcess.StartInfo.FileName = commandPath; 
     myProcess.StartInfo.Arguments = formattedArgumets; 
     myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     myProcess.StartInfo.WorkingDirectory = this.workingDirectory; 
     myProcess.Start(); 
     myProcess.WaitForExit(); 
    } 
} 

Когда звоню его тис образом:

private void RunCommands() 
{ 
    var command = "LongRunCommand.exe"; 
    string binDirectory = Path.Combine(FileSystem.ApplicationDirectory, binFolderName); 
    var cp = new CommandProcessor(this.workingDirectory, binDirectory); 
    for(int i=0;i<10;i++) 
    { 
     cp.RunCommand(Command, "-i {0}", i); 
    } 
} 

Приведенный выше код называется часть прямого вызова и блокирует приложения (приложения похоже, висит во время этого процесса.

Чтобы решить проблему висячего, я использовал фонового работника следующим образом:

var worker = new BackgroundWorker(); 
    worker.DoWork += this.WorkerDoWork; 
    worker.RunWorkerCompleted += this.workerRunWorkerCompleted; 
    worker.RunWorkerAsync(); 

и называется runcommand внутри WorkerDoWork.

Теперь приложение вышло после того, как он назвал эту строку:

myProcess.WaitForExit(); 

Там нет информации отладки и коды выхода -1.

В чем проблема и как ее решить?

Есть ли лучший способ достичь моей цели, не используя BackgroundWorker?

ответ

0

Проблема, с которой вы столкнулись, связана с тем, что потоки BackgroundWorker все еще запущены, но приложение завершает жизненный цикл и заканчивается (он не блокируется ими, поэтому его путь ясен до конца), поэтому он убивает эти потоки.

Вы должны сообщить об этом заявлению NOT, чтобы завершить работу, пока потоки фона все еще работают. У вас может быть счетчик, который увеличивается при каждом запуске каждого потока, а затем по завершении они могут уменьшить счетчик.

Внутри основной темы приложения вы можете подождать, пока счетчик не достигнет нуля до окончания приложения.

Очевидно, что вам нужно будет учитывать блокировку (то есть два потока пытаются уменьшить счетчик одновременно), но это должно дать вам стартер.

Смежные вопросы