2012-12-31 54 views
5

我正在編寫一個應用程序,其中有一個運行在BackgroundWorker中的進程。我想支持從用戶界面取消,但我沒有看到一個簡單的方法來做到這一點。取消通過System.Diagnostics.Process.Start()啓動的進程

Process實際上是一個相當長的運行命令行EXE。輸出通過Progress.OutputDataReceived事件異步重定向,並用於向GUI報告進度。

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    using (var process = new Process()) 
    { 
     //... 

     process.Start() 

     //... 

     process.WaitForExit(); 
    } 
} 

private void CancelWorker() 
{ 
    worker.CancelAsync(); 
    // where to actually listen for the cancellation??? 
} 

似乎沒有成爲一個辦法讓過程「監聽」從StandardInput主線程拋開任何輸入,但是這是行不通的,除非應用程序本身會響應特定的輸入中止。

有沒有辦法根據主線程的取消請求取消進程?

對於在運行的過程中的EXE的我,我可以叫Process.Close()退出無任何副作用的目的,但Process對象僅已知worker_DoWork()方法,所以我需要跟蹤Process實例爲取消目的...這就是爲什麼我希望有更好的方法。

(如果它很重要,我針對.NET 3.5的兼容性問題。)

+1

有你開始一個過程,一個BG工人理由嗎?這通常是一個不需要很長時間的調用(程序啓動可能需要一段時間才能加載,但這將在其自己的過程中)。 – keyboardP

+0

它實際上不是在後臺工作,但是在自定義的異步方法中,BackgroundWorker似乎更容易描述這種情況。但原因是這是在後臺線程中運行的更大進程的一部分。 – psubsee2003

+0

CancelAsync將無法工作,因爲該線程在幾毫秒內完成了其作業,除非在該DoWork方法中有重負載。儘管'using'是一種很好的做法,因爲您需要能夠從代碼的其他地方訪問'Process',您可以擁有一個類級變量來保存'Process'並調用'Process.Close'。只要記得在線程返回或不再需要該進程時在進程上調用Dispose。 – keyboardP

回答

3

對於合作消除,你需要聽BackgroundWorker.CancellationPending in BackgroundWorker.DoWork 事件。

How to: Use a Background Worker

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    using (var process = new Process()) 
    { 
     //... 

     process.Start() 

     //... 
     while(true) 
     { 
      if ((sender as BackgroundWorker).CancellationPending && !process.HasExited) 
      { 
       process.Kill(); 
       break; 
      } 
      Thread.Sleep(100); 
     } 

     process.WaitForExit(); 
    } 
} 
+0

好的建議,但是因爲'while(true)',循環永遠不會退出,除非收到取消。我將它改爲'while(!process.HasExited)',它完美的工作,謝謝。 – psubsee2003

-1

試試這個,這可能是幫助你,在簡單的方法

private System.Threading.TimerCallback worker; 
private System.Threading.Timer workertimer ; 
private void worker_DoWork() 
{ 
    //You codes 
} 
private void StartWorker() 
{ 
    worker = new System.Threading.TimerCallback(worker_DoWork); 
    workertimer = new System.Threading.Timer(worker, null, 1000, 1000); 
} 

private void CancelWorker() 
{ 
    worker.Dispose(); 
} 
+2

我不明白,'處理'是如何在'Dispose'方法中被殺死的。它如何工作? – Tilak

相關問題