2011-11-28 65 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; 

         } 
       } 

    } 
}