BackgroundWorker 在执行DoWork事件时该如何取消呢?

方法1 DoWork 执行一个(耗时)循环

方法2 DoWork执行一个(耗时)方法[注:方法没有循环]

见代码:

方法1中DoWork事件执行的是一个for循环(foreach,while.....)

取消操作很简单,只要在循环中判断即可

看代码---------代码是从网上拷贝下来的,这种例子网上很多

#region
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Threading;
using System.Text.RegularExpressions; namespace ConsoleBackgroundworker
{
class Program
{
static BackgroundWorker bw;
static void Main()
{
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.RunWorkerAsync("Hello to worker");
Console.WriteLine("Press /"C/" to cancel"); while (true)
{
//按C取消
if (Console.ReadKey(true).Key == ConsoleKey.C)
{
if (bw.IsBusy)
bw.CancelAsync(); //提交取消命令,但还未取消
else { break; }
}
}
//Console.ReadLine();
} static void bw_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine(e.Argument);
for (int i = ; i <= ; i += )
{
//判断是否取消操作
if (bw.CancellationPending)
{
e.Cancel = true; //这里才真正取消
return;
}
//传递给ProgressChanged
bw.ReportProgress(i);
Thread.Sleep();
e.Result = i;
}
// 最终传递给RunWorkerCopmleted
} static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
Console.WriteLine("You cancelled!");
else if (e.Error != null)
Console.WriteLine("Worker exception: " + e.Error.ToString());
else
{
Console.WriteLine("Complete - " + e.Result); // 从 DoWork 传过来的参数
}
} static void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.Write("{0,3}/b/b/b", e.ProgressPercentage);
}
}
}
#endregion

方法2中DoWork事件中执行的是一个比较耗时的方法时该怎么办了.方法中没有循环无法判断用户是否执行了取消操作!

那么这里就要用到[异步编程模式],在执行一个比较耗时的方法时,代码还能继续向下运行.....!

请看下面代码-----------此代码是本人自己写的

BackgroundWorker bgworker = new BackgroundWorker();
gworker.WorkerSupportsCancellation = true; //是否支持异步取消 如果要取消操作必须设置true
bgworker.DoWork += new DoWorkEventHandler(this.bgworker_DoWork);
bgworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.bgworker_RunWorkerCompleted); private void begin_Click(object sender, EventArgs e)
{
//开始
if(!bgworker.IsBusy)
{
bgworker.RunWorkerAsync(); //开始操作
}
} private void end_Click(object sender, EventArgs e)
{
//开始取消
if (bgworker.IsBusy) //是否在运行异步操作
{
bgworker.CancelAsync(); //(是)提交取消命令
}
} private void bgworker_DoWork(object sender, DoWorkEventArgs e)
{
//Sql语句 查询的数据很多
string sql = "select * from table"; //绑定委托要执行的方法
Del_DoWork work = new Del_DoWork(ReturnDataTable); //可以使用:delegate、Action、Func、predicate 等,具体可参考:C#委托的介绍(delegate、Action、Func、predicate)委托的N种写法 //开始异步执行(ReturnDataTable)方法
IAsyncResult ret = work.BeginInvoke(sql, null, null); //(异步编程模式好久就是在执行一个很耗时的方法(ReturnDataTable)时,还能向下继续运行代码) //接着运行下面的while循环,
//判断异步操作是否完成
while (!ret.IsCompleted)
{
//没完成
//判断是否取消了backgroundworker异步操作
if (bgworker.CancellationPending)
{
//如何是 马上取消backgroundwork操作(这个地方才是真正取消)
e.Cancel = true;
return;
}
}
e.Result = work.EndInvoke(ret); //返回查询结果 赋值给e.Result
} private delegate DataTable Del_DoWork(string sql); //创建一个委托
/// <summary>
/// 查询数据库表--------一个很耗时的方法
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
private DataTable ReturnDataTable(string sql)
{
DataTable table = new DataTable();
SqlConnection conn = new SqlConnection("Server............");
//.....................(省略)
return table;
} private void bgworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("您取消了操作!");
}
else if (e.Error != null)
{
MessageBox.Show("出现错误!");
}
else
{
DataTable table = e.Result as DataTable;
if (table != null)
{
//得到数据,进行显示操作
//dataGridView1.DataSource = table;
}
}
}

我这里主要是方法2,在很多情况下,我们的DoWork事件都是执行一个方法,而不是一个循环....如果你也遇到要执行一个耗时方法,又要取消操作的话,请用方法2吧!

出处:https://www.cnblogs.com/therock/articles/2155511.html

https://www.cnblogs.com/MLGB/p/4027244.html

C# 如何取消BackgroundWorker异步操作的更多相关文章

  1. React Native性能优化之可取消的异步操作

    前沿 在前端的项目开发中,异步操作是一个不可获取的,从用户的角度来说,异步操作所带来的体验是美妙的,但有时候也会带来一些性能隐患.比如说:有一个异步请求还没有返回结果,但是页面却关闭了,这时由于异步操 ...

  2. 异步委托方式取消BackGroundWorker执行无循环的耗时方法

    边学习边分享,纯属抛砖引玉. 线程的一个好处是异步的执行操作,在winform中,很多耗时操作执行时,为优化用户体验,避免长时间等待,从而运用线程技术异步的执行耗时操作,但不会阻塞主线程. 最近系统很 ...

  3. 【.NET异步编程系列3】取消异步操作

    在.Net和C#中运行异步代码相当简单,因为我们有时候需要取消正在进行的异步操作,通过本文,可以掌握 通过CancellationToken取消任务(包括non-cancellable任务).  早期 ...

  4. 【你不一定知晓的】C#取消异步操作

    [你不一定知晓的]C#取消异步操作 在.Net和C#中运行异步代码相当简单,因为我们有时候需要取消正在进行的异步操作,通过本文,可以掌握 通过CancellationToken取消任务(包括non-c ...

  5. 【异步编程】Part3:取消异步操作

    在.Net和C#中运行异步代码相当简单,因为我们有时候需要取消正在进行的异步操作,通过本文,可以掌握 通过CancellationToken取消任务(包括non-cancellable任务).  早期 ...

  6. BackgroundWorker控件

    在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示 ...

  7. backgroundworker组件的使用

    本文转载:http://www.cnblogs.com/inforasc/archive/2009/10/12/1582110.html BackgroundWorker 组件用来执行诸如数据库事务. ...

  8. C# BackgroundWorker使用总结

    查询了一下MSDN文档,其中微软就BackgroundWorker类的功能有这么一个描述(英文的,根据个人理解翻译):BackgroundWorker类允许您在单独的线程上执行某个可能导致用户界面(U ...

  9. BackgroundWorker学习笔记

    1 简介 BackgroundWorker 类允许您在单独的专用线程上运行操作. 耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态. 如果您需要能进行响 ...

随机推荐

  1. Jenkins - 插件管理

    1 - Jenkins插件 Jenkins通过插件来增强功能,可以集成不同的构建工具.云平台.分析和发布工具等,从而满足不同组织或用户的需求. Jenkins 提供了不同的的方法来安装插件(需要不同级 ...

  2. 【python小记】访问mysql数据库

    题记: 最近因为工作需要,学习了python,瞬间对这个轻松快捷的语给吸引了,以前只知道js脚本是写网页的,没有想到python这个脚本语言的应用范围可以这么广泛,现在做一些简单或稍微复杂的操作,基本 ...

  3. P-R曲线深入理解

    P-R曲线就是精确率precision vs 召回率recall 曲线,以recall作为横坐标轴,precision作为纵坐标轴.首先解释一下精确率和召回率. 解释精确率和召回率之前,先来看下混淆矩 ...

  4. javascript 代码实例

    数组去重 function unique(arr){ if(!Array.isArray(arr)){ console.log('type error!'); return; } arr = arr. ...

  5. Huawei重新开启隐藏桌面功能

    在HUAWEI的EMUI系统7.0的时候我们都能发现桌面上靠手指操作的隐藏桌面的功能,像这样: 但是在之后的EMUI8.0.9.0,之后就没有办法用了.后来问了官方,这个功能确实是被去掉了.个人也很不 ...

  6. 在右键菜单中添加用Jupyter Notebook打开

    在右键菜单中添加用Jupyter Notebook打开 为了把 Jupyter 的工作目录指定到某一个文件夹下,每次都要启动 CMD 终端, 然后激活 Anaconda 环境,再启动 Jupyter ...

  7. ②将SVN迁移到GitLab-多分支多标签迁移

    之前我们介绍了<①将SVN迁移到GitLab-单分支迁移>,文中研究了svn迁移到git单分支的操作过程,本文针对实际开发过程中svn使用到的trunk.branches.tags情况进行 ...

  8. MySQL事务和事务隔离级别

    1.概述 事务就是对数据库数据进行更改(包括insert.update.delete等)操作的一个执行单元,通常有一条或多条更改语句组成.在同一个事务中的更改操作要么同时成功,要么同时失败. 事务具有 ...

  9. Celery定时任务细讲

    Celery定时任务细讲 一.目录结构 任务所在目录 ├── celery_task # celery包 如果celery_task只是建了普通文件夹__init__可以没有,如果是包一定要有 │ ├ ...

  10. 超详细Vue实现导航栏绑定内容锚点+滚动动画+vue-router(hash模式可用)

    超详细Vue实现导航栏绑定内容锚点+滚动动画+vue-router(hash模式可用) 转载自:https://www.jianshu.com/p/2ad8c8b5bf75 亲测有效~ <tem ...