2012-04-20 6 views
0

현재 C# 프로젝트에서 작업 중이며 System.Diagnostic.Process 클래스를 사용하고 있습니다.스레드를 통해 시작된 프로세스 닫기

내 프로그램이 시작되면 새 스레드가 만들어지고 각 스레드 내에서 다른 프로세스가 시작됩니다.

어느 시점에서 각 프로세스가 계속 실행되어야하는지 또는 중지되어야하는지 여부를 확인하려면 프로그램 내에서 설정을 확인해야하지만 특정 스레드가 시작한 프로세스를 어떻게 참조 할 수 있는지는 알 수 없습니다. 프로세스가 시작될 때마다 이름을 부여한 각 스레드가 있지만 C#은 스레드를 생성하고 프로세스를 시작한 다음 프로세스가 여전히 실행 중이고 출력을받는 경우에도 스레드를 닫습니다.

어떤 프로세스가 어떤 스레드에 의해 시작되었고 그 프로세스가 실행되지 않았는지 알 수있는 방법이 있습니까?

그러나 어떻게이 스레드 이름을 기반으로 프로세스를 중지 할 수 있도록이 메서드와 사전을 사용할 수 있는지 알 수 없습니다.

업데이트 아래 요청은 스레드에서 각 프로세스를 만드는 코드입니다. 사전에 스레드를 사용하고 있으므로 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

왜 스레드 이름을 사용합니까? 이 활동을 풀면, 어떤 스레드가 특정 프로세스를 실행할지 전혀 알 수 없습니다.

프로세스를 관리하는 경우 프로세스 이름, 프로세스 EXE 경로, 프로세스 핸들, 프로세스가 완료 될 때까지 핸들 대기중인 스레드, 모든 상태 열거 형 및 프로세스 이름에 대한 필드 및 속성을 포함 할 수있는 'managedProcess' 필드를 스레드로부터 안전하게 유지하기위한 뮤텍스, 프로세스를 시작하고 중지하는 메소드 - 프로세스와 관련된 모든 것. 이 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

도움을 주셔서 감사합니다.하지만이 작업은 각 루프에 대해 새 프로세스로 시작되지 않으므로 각 이름을 지정할 수 없습니다. proces 그래서 어떤 프로세스가 무엇을 닫아야할지 모른다. – Boardy

+0

@Boardy 백업하자. foreach 루프로 프로세스를 생성합니다. 각 스레드는 N 개의 프로세스를 시작하는 루프를 가지고 있습니까? 아니면 각각 단일 프로세스를 시작하는 N 개의 스레드를 생성하는 루프입니까? 각 프로세스가 이론적으로 동일한 이름을 가졌습니까 _ 또는 주어진 프로세스에 대해 고유 한 스레드 이름입니까? –

+0

@Boardy 스레드와 프로세스를 만드는 방법을 보여주는 코드를 게시 할 수 있다면 좋을 것입니다. –

관련 문제