2010-03-26 63 views
1

在我的應用程序中,我有一個主窗口並進入它,在一個框架中加載一個頁面。當用戶按下按鈕時,該頁面執行很長時間的任務。我的問題是,當長時間的任務正在做,用戶按下主窗口的關閉按鈕,應用程序似乎沒有完成,因爲我在VS2008中調試它,我可以看到突出顯示停止按鈕。如果我想完成,我必須按停止按鈕,應用程序不會在應用程序退出時自動停止調試。我認爲.NET會在應用程序退出時自動停止backgroundworkers,但在看到此行爲後我不確定。我曾試圖強制並取消後臺工作人員在卸載活動頁面中,如下所示:wpf在應用程序退出時取消backgroundworker

private void Page_Unloaded(object sender, RoutedEventArgs e) 
    { 
     // Is the Background Worker do some work? 
     if (My_BgWorker != null && My_BgWorker.IsBusy) 
     { 
      //If it supports cancellation, Cancel It 
      if (My_BgWorker.WorkerSupportsCancellation) 
      { 
       // Tell the Background Worker to stop working. 
       My_BgWorker.CancelAsync(); 
      } 
     } 


    } 

但沒有成功。幾分鐘後,我做了CancelAsync()後,我可以看到backgroundworker完成並引發RunWorkerCompleted,並且我可以看到任務已完成,檢查事件中的e.Cancelled參數,但在此事件執行後,應用程序繼續而不退出,不知道在做什麼....

我將WorkerSupportsCancellation設置爲true以支持在開始時取消。

我會apreciate所有答案。謝謝。

回答

4

取消不是自動的,您在DoWork事件處理程序中的代碼需要通過檢查CancellationPending屬性的值來處理取消操作。調用CancelAsync不會中止線程,它只是設置CancellationPending爲true ...

例如:

private void bgw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while(!bgw.CancellationPending) 
    { 
     ... 
    } 
} 
+0

好的,當我做My_BgWorker.CancelAsync();從執行backgroundworker的頁面開始,它將CancellationPending設置爲true,現在我在DoWork中檢查此屬性值。然後,當它是真實的我完成的DoWork方法,但我不明白一兩件事:退出後的DoWork時RunWorkerCompleted事件引發的爭論ê作爲RunWorkerCompletedEventArgs應該是因爲我做了e.Cancelled =真不虛: My_BgWorker.CancelAsync ()或者我很困惑?爲什麼我收到e.cancelled爲false,如果我已經請求使用CancelAsync()取消後臺操作,則不會返回true? – toni

+0

e.Cancel應該在DoWork的事件設置,如果取消請求已經被考慮到 –

+0

是,在DoWork的事件,我把一個破發點,在它和​​CancellationPending設置爲true結束,但RunWorkerCompleted當事件後引發DoWork完成後,RunWorkerCompleted中的e.Cancelled屬性爲false。這是正常的嗎?不應該是真的(因爲我要求取消背景工作操作)? – toni

0

我認爲托馬斯Levesque的精確定位的問題。

一般說明:某處某個線程仍在執行。通過暫停調試過程(暫停按鈕,名爲「Break All」),您可以嘗試找出是哪個線程。此時,下一條執行的代碼行應該高亮顯示。此外,您可以使用線程窗口(在Debug - > Windows下)來確切地查看哪個線程仍在運行,以及在哪裏。

+0

好吧,我已經做了你說的話,按下按鈕暫停,但沒有行highlihted並在線程窗口,我能看到的只有一個處理GParts.vshost.exe。在按下關閉按鈕應用程序後,我可以看到DoWork方法已完成,然後將eWorkCalllled參數引發的RunWorkerCompleted事件設置爲false(我不明白,因爲我對Thomas說過爲什麼它未設置爲true,因爲我使用cancelASync())並且應用程序似乎不退出(不停止調試)。在這種情況下,我暫停調試,沒有一行被突出顯示,我進入線程窗口,你說,它出現一個進程。 – toni

-1

完美的托馬斯,將ShutdownMode設置爲OnMainWindowClose,正如你所說的解決了我的問題。現在調試器正確停止;)非常感謝您的幫助。

我所做的是:

 <Application 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"       
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     x:Class="GParts.App" 
     StartupUri="WinMain.xaml" 
     ShutdownMode="OnMainWindowClose"> 

        <...> 

     </Application> 

最後,我願做一點件事就的BackgroundWorker的DoWork的事件情況下的例外是由某些類型的錯誤拋出:我hanlde裏面的錯誤與嘗試catch子句和成抓我做的:

 catch (Exception ex) 
     { 
      e.Result = ex.Message;    
     } 

當一個例外,我想在RunWorkerCompleted與e.Error檢測到它,並顯示它BackgroundWorker的完成。所以我在RunWorkerCompleted中做的是:

 if (e.Cancelled) 
     { 
      // Cancelled 

     } 
     else if (e.Error != null) 
     { 
      // Exception Thrown 
      // Here I want to show the message that produced the exception in DoWork 
      // event. If I set e.Result = ex.Message in DoWork event, is e.Error here 
      // containing ex.Message? 


     } 
     else 
     { 
      // Completed); 
     } 

RunWorkerCompleted中是否包含ex.Message中的e.Error?

謝謝。