2014-06-09 75 views
0

我有一個BackgroundWorker在後臺執行工作。該工作是在命令提示符下運行一些.exe應用程序並等待輸出顯示。有時.exe應用程序堆棧或需要很長時間。如果它仍在運行,我想在一分鐘後停止工人。 問題是我有一個進度條,在主線程中運行1分鐘。當進度條已滿(1分鐘後)來自主線程(UI)時,我想停止該工作人員。這裏是我的代碼:WPF從主線程停止BackgroundWorker

private void btnTest_Click(object sender, RoutedEventArgs e) 
    { 

     wTest = new BackgroundWorker(); 
     wTest .DoWork += new DoWorkEventHandler(wTest _DoWork); 
     wTest .RunWorkerCompleted += wTest _RunWorkerCompleted; 
     wTest .WorkerReportsProgress = true; 
     wTest .WorkerSupportsCancellation = true; 
     wTest .RunWorkerAsync(); 

     while (pbTest.Value < 91) 
     {    
      if (!wTest.CancellationPending) 
      { 
       pbTest.Value = (pbTest.Value + 100/60); 
       Thread.Sleep(1000); 
      } 
      Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, 
             new ThreadStart(delegate { })); 
     } 
    } 

    void wTest_DoWork(object sender, DoWorkEventArgs e) 
    { 
     //call .exe application and wait for output 
    } 

我該怎麼辦?

+0

停止後臺工作或停止它啓動的過程? –

+0

我想阻止工人。我可以認爲它會阻止這個過程呢? – user3719173

回答

0

你需要做的是有你的DoWork委託支票e.Cancel(在DoWorkEventArgs)財產帶來設爲true。如果DoWork被阻止,就像等待StandardOutput一樣,那麼這根本就不可能。

另一種方法是通過Process.WaitForExitint說明它應該等待多長時間輸出:

process.WaitForExit(60000); 
1

如果您使用的是.NET 4.5,你可以使用Task類和相關CancellationTokeSourceCancellationToken類。請注意,任務通過IProgress界面支持報告進度。 Stephen Cleary在這方面有很好的example

如果您正在進行的工作未提供異步界面,您可以使用Task.Run來執行它並通過CancellationToken來監視取消。在您完成工作時,您需要監視令牌以取消。要做到這一點的一種方法是致電ThrowIfCancellationRequested,如果在CancellationTokenSource上調用Cancel,將拋出OperationCancelledExceptionCancellationTokenSource也支持一段時間後取消,這對您的方案來說很方便。

private CancellationTokenSource cts; 

private void btnTest_Click(object sender, RoutedEventArgs e) 
{ 
    if(cts == null) 
    { 
     cts = new CancellationTokenSource(new TimeSpan(0, 0, 60)); // cancel after 60 seconds 
    } 

    await Task.Run(() => Work(), cts.Token); 

    cts = null; 
} 

void Work(CancellationToken token) 
{ 
    // do work 
    token.ThrowIfCancellationRequested(); 
    // do work 
} 
+0

我正在使用.NET 3.5。這個類是包含在.NET 4 – user3719173

+0

好的,我會提到我的答案是.net 4.5 –

+0

有沒有辦法做到.net 3.5? – user3719173

1

您需要做兩件事才能取消您的BackgroundWorker工作。首先,你需要在你的DoWork處理方法來檢查BackgroundWorker.CancellationPending property

private void wTest_DoWork(object sender, DoWorkEventArgs e) 
{ 
    //call .exe application and wait for output 
    if (worker.CancellationPending) 
    { 
     e.Cancel = true; 
    } 
} 

然後,當你要取消的工作,你應該叫上你的BackgroundWorker這樣的:

backgroundWorker.CancelAsync(); 

然而,因爲你是而不是使用BackgroundWorker,因爲它是爲了使用,我不認爲這會適用於你。如果您正在等待第三方應用程序啓動,那麼您將無法將e.Cancel屬性設置爲true

說實話,我不明白你爲什麼只用BackgroundWorker來啓動一個進程。 Process.Start方法沒有時間完成,因爲它不等待任何響應。在我看來,你最好監測Process.Exited event,並改爲撥打Process.Kill method