2012-04-20 2 views
0

В настоящее время я работаю над проектом C# и использую класс System.Diagnostic.Process.Закрытие процесса, который был запущен через поток

Когда моя программа запускается, создается новый поток, и внутри каждого потока начинается другой процесс.

В какой-то момент мне нужно проверить настройку в моей программе, чтобы увидеть, должен ли каждый процесс продолжать работать или он должен быть остановлен, но я не знаю, как я могу ссылаться на процесс, который был запущен определенным потоком. Каждый поток, который я дал имени при запуске процесса, но я понимаю, что C# создает поток, запускает процесс и затем закрывает поток, даже если процесс все еще работает и все еще получает выход.

Есть ли способ узнать, какой процесс был запущен потоком и отменить этот процесс.

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

UPDATE В качестве следующего запроса используется код, который я использую, который создает каждый процесс в потоке. Я использую поток в словаре, так что я могу ссылаться на него из события outputreceived, но не знаю, как это сделать, если мне нужно закрыть процесс.

Thread worker = new Thread(new ThreadStart(() => startProducts(product.Value[0].startScript, product.Value[0].productName))); 
       worker.IsBackground = false; 
       worker.Name = product.Value[0].productName; 
       worker.Start(); 
       logging.logger(string.Format("Starting product '{0}'", product.Value[0].productName)); 

Метод, который вызывает поток, заключается в следующем: здесь начинается каждый процесс. Гарантируется, что каждый процесс имеет именованный нить, никогда не будет двух потоков с тем же именем.

private void startProducts(string startScript, string product) 
     { 
      Process startProductProcess = new Process(); 
      startProductProcess.StartInfo.FileName = startScript; 
      if (configManagement.productConfig[product][0].requireArguments == true) 
      { 
       startProductProcess.StartInfo.Arguments = configManagement.productConfig[product][0].arguments; 
      } 
      startProductProcess.StartInfo.UseShellExecute = false; 
      startProductProcess.StartInfo.RedirectStandardOutput = true; 
      StringBuilder processOutput = new StringBuilder(""); 
      startProductProcess.OutputDataReceived += new DataReceivedEventHandler(startProductProcess_OutputDataReceived); 
      startProductProcess.Exited += new EventHandler(startProductProcess_Exited); 
      processTag.Add(startProductProcess, product); 
      startProductProcess.Start(); 
      //Process localByName = Process.GetProcessById(startProductProcess.Id); 
      startProductProcess.BeginOutputReadLine(); 
      logging.logger(string.Format("Started {0} with: {1} {2}", product, 
       startProductProcess.StartInfo.FileName, startProductProcess.StartInfo.Arguments)); 
     } 
+2

Похоже, что вы должны использовать словарь и сохранять каждый процесс в словаре с чем-то вроде StatusEnum. – SimpleVar

+0

Я думаю, что для выходного события уволен. Я добавлю код, чтобы он мог помочь. – Boardy

ответ

0

Зачем использовать название нити? Если бы вы отключили эту активность, вы не знаете, какой поток будет запускать какой-либо конкретный процесс.

Если вы управляете процессами, определите класс «managedProcess», который может содержать поля и свойства для имени процесса, обрабатывать путь EXE, обрабатывать дескриптор, поток, ожидающий на дескрипторе процесса для завершения, любое перечисление состояния, любой мьютекс, чтобы сохранить поля в потоковом режиме, методы для его запуска и остановки - что-то связанное с процессом. Вызовите экземпляры этого класса managedProcess в свой контейнер.

IMHO, забыть названия потоков для чего угодно, кроме отладки.

Завершение - в методе stop() вы можете попробовать опубликовать WM_CLOSE (можете ли вы сделать это напрямую или это P/Invoke?), Ожидая нескольких секунд, чтобы увидеть, ожидает ли поток ожидающих сигналов, что процесс закрылся и, если нет, вызовите TerminateProcess(), (или все, что управляется для TerminateProcess).

0

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

Dictionary<string, Process> processesByName = new Dictionary<string, Process>(); 
Process firstProcess = ... //Start your process 
Process secondProcess = ... //Start your process 
processesByName.Add("FirstProcessName", firstProcess); 
processesByName.Add("SecondProcessName", secondProcess); 

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

Process process = processesByName["FirstProcessName"]; 
if (!process.HasExited) 
{ 
    process.CloseMainWindow(); 
    process.Close(); 
} 
+0

Спасибо за вашу помощь, но это не сработает, так как новый процесс запускается внутри каждого цикла, поэтому я не могу назвать каждый поэтому я не буду представлять, какие процессы - это то, что закрыть. – Boardy

+0

@Boardy Давайте резервную копию. Вы создаете процессы в цикле foreach. В каждом потоке есть цикл, который запускает N процессов или представляет собой цикл, несущий N потоков, каждый из которых запускает один процесс? Может ли каждый процесс теоретически иметь одно и то же имя_ или имя потока, уникальное для данного процесса? –

+0

@Boardy Если вы можете опубликовать код, показывающий, как вы создаете потоки и процессы, это было бы хорошо. –

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