.net 取消e.result中的后台工作程序异常
我和背景工作者有严重的问题。如果任务结束,则代码正常工作。当我取消后台任务时,在e.Result的RunWorkerCompleted函数中会出现system.invalidoperationexception。怎么了?多谢各位 这是我的cod:.net 取消e.result中的后台工作程序异常,.net,backgroundworker,.net,Backgroundworker,我和背景工作者有严重的问题。如果任务结束,则代码正常工作。当我取消后台任务时,在e.Result的RunWorkerCompleted函数中会出现system.invalidoperationexception。怎么了?多谢各位 这是我的cod: private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { if (backgroundWorker.CancellationPending == true)
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;
}
private void backgroundWorker\u DoWork(对象发送方,DoWorkEventArgs e)
{
if(backgroundWorker.CancellationPending==true)
e、 取消=真;
e、 结果=结果列表;
}
私有void backgroundWorker1\u RunWorkerCompleted(对象发送方,runworkercompletedeventarge)
{
如果(例如错误!=null)
List resultList=(List)e.Result;
}
这是根据设计,当DoWork被取消或抛出异常时,结果属性getter将抛出。只需检查一下:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (!e.Cancelled && e.Error == null) {
List<Object> resultList = (List<Object>)e.Result;
// etc..
}
}
private void backgroundWorker1\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
如果(!e.Cancelled&&e.Error==null){
List resultList=(List)e.Result;
//等等。。
}
}
经过长期的努力(作为新手),我成功地将@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;
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
使用系统组件模型;
使用系统数据;
命名空间取消BackgroundWorker
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
私有BackgroundWorker worker=null;
公共主窗口()
{
初始化组件();
worker=新的BackgroundWorker();
worker.worker支持扫描单元=true;
worker.WorkerReportsProgress=true;
worker.DoWork+=worker\u DoWork;
worker.ProgressChanged+=worker\u ProgressChanged;
worker.RunWorkerCompleted+=worker\u RunWorkerCompleted;
}
私有void btnStart\u单击(对象发送方,路由目标)
{
worker.RunWorkerAsync();
}
私有void btnCancel\u单击(对象发送者、路由目标)
{
worker.CancelAsync();
}
无效工作线程(对象发送器,工作线程目标)
{
对于(int i=0;i而不是将e.Cancel设置为true(这会导致异常),您可以在DoWork事件中将类设置为e.Result,该事件包含您的结果和一个指示任务是否完成的变量。或者,如果您的c#是最新的,您可以简单地将其设置为元组
…在嫁妆中
while(doingWork) {
if(worker.CancellationPending) {
e.Result = (false, resultList);
return;
}
resultList.Add(someResult);
}
e.Result = (true, resultList);
…在RunWorkerCompleted中
var (completed, resultList) = (bool, WhateverListTypeYouUsed)e.Result;
if(completed) Debug.WriteLine("Hooray!");
当然,这是假设您想知道任务是否完成。ah ok,但是如果取消,我需要结果事件,该怎么办?仔细想想:如果DoWork被取消或被异常中断,那么您就无法得到有效的结果。它没有完成。它被故意取消:用户可以中止耗时的任务k、 然后调用backgroundWorker.CancelAsync(),还没有异常。我想向用户显示到目前为止的结果。如何做到这一点,我没有任何结论。如果不将e.Cancel属性设置为true,只需分配e.result并退出即可。使用CancelAsync()将backgroundWorker.CancellationPending设置为true。不要将e.Cancel设置为true.Simple。