2011-11-28 53 views
3

我有一個嚴重的問題與後臺工作。代碼正在工作,如果任務正常結束。當我取消後臺任務時,我在e.Result的RunWorkerCompleted函數中得到了system.invalidoperationexception。哪裏不對?謝謝。取消e.result中的後臺工作者異常

這裏是我的鱈魚:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    if (backgroundWorker.CancellationPending == true) 
    e.Cancel = true; 
    e.Result = resultList; 
} 


private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Error != null) 
    List<Object> resultList = (List<Object>)e.Result; 
} 

回答

5

這是由設計,當DoWork的被取消或拋出異常Result屬性的getter會拋出。只需檢查:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (!e.Cancelled && e.Error == null) { 
     List<Object> resultList = (List<Object>)e.Result; 
     // etc.. 
    } 
} 
+1

啊好的,但做什麼,如果我需要如果取消導致事件? – user1069951

+1

想一想:如果DoWork被異常取消或中斷,那麼你不能得到有效的結果。它沒有完成。 –

+0

它被意圖取消:用戶可以放棄一個耗時的任務,然後backgroundWorker.CancelAsync()被調用,但沒有例外。我想向用戶介紹迄今爲止的結果。 我怎麼能這樣做,我不知道 – user1069951

0

經過漫長的鬥爭(作爲新手),我設法將@ Hans的建議與我的代碼結合起來。希望以下代碼塊可幫助像我這樣的初學者在調用cancelasync()時返回當前處理的結果。

代碼塊

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

using System.ComponentModel; 
using System.Data; 

namespace CancelBackgroundWorker 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     private BackgroundWorker worker = null; 

     public MainWindow() 
     { 
      InitializeComponent(); 
         worker = new BackgroundWorker(); 
         worker.WorkerSupportsCancellation = true; 
         worker.WorkerReportsProgress = true; 
         worker.DoWork += worker_DoWork; 
         worker.ProgressChanged += worker_ProgressChanged; 
         worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
     } 


       private void btnStart_Click(object sender, RoutedEventArgs e) 
       { 
         worker.RunWorkerAsync(); 
       } 

       private void btnCancel_Click(object sender, RoutedEventArgs e) 
       { 
        worker.CancelAsync(); 


       } 

       void worker_DoWork(object sender, DoWorkEventArgs e) 
       { 

        for(int i = 0; i <= 100; i++) 
         { 
           if(worker.CancellationPending == true) 
           { 
            //http://stackoverflow.com/questions/8300799/cancel-background-worker-exception-in-e-result 
             // e.Cancel = true; //This does the trick 
             e.Result = 100; 
             return; 
           } 
           worker.ReportProgress(i); 
           System.Threading.Thread.Sleep(250); 

         } 
         e.Result = 42; 

       } 

       void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
       { 
         lblStatus.Text = "Working... (" + e.ProgressPercentage + "%)"; 
       } 

       void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
       { 
         if(e.Cancelled) 
         { 
           lblStatus.Foreground = Brushes.Red; 
           lblStatus.Text = "Cancelled by user..." + e.Result; 

         } 
         else 
         { 
           lblStatus.Foreground = Brushes.Green; 
           lblStatus.Text = "Done... Calc result: " +e.Result; 

         } 
       } 

    } 
}