2012-04-20 51 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 2012-04-20 12:55:42

+0

我想我是爲輸出事件解僱我會添加一些代碼,所以它可能會幫助 – Boardy 2012-04-20 12:58:12

回答

0

爲什麼要使用線程名稱進行任何操作?如果你想將這個活動集中起來,你就不知道哪個線程將運行任何特定的過程。

如果您在管理進程,請定義一個'managedProcess'類,該類可以包含進程名稱的字段和屬性,處理EXE路徑,進程句柄,等待進程完成的進程的線程,任何狀態枚舉,任何互斥體保持字段線程安全,啓動它並停止它的方法 - 與進程有關的任何事情。將此managedProcess類的實例移到您的容器中。

恕我直言,忘了除調試以外的任何線程名稱。

終止 - 在您的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 2012-04-20 18:48:30

+0

@Boardy讓我們回去吧。你正在foreach循環中創建進程。每個線程都有一個循環啓動N個進程,還是循環產生N個線程,每個線程啓動一個進程?理論上每個處理過程可能具有相同的名稱嗎?或者是給定過程唯一的線程名稱? – 2012-04-20 18:56:53

+0

@Boardy如果你可以發佈代碼來顯示你是如何創建線程和進程的,那很好。 – 2012-04-20 19:00:11

相關問題