LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# 如何取消BackgroundWorker异步操作

admin
2021年2月21日 17:11 本文热度 2345

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 = 0; i <= 100; i += 1)

      {

        //判断是否取消操作

        if (bw.CancellationPending)

        {

          e.Cancel = true; //这里才真正取消

          return;

        }

        //传递给ProgressChanged

        bw.ReportProgress(i);

        Thread.Sleep(100);

        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); //可以使用:delegateActionFuncpredicate 等,具体可参考: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);  //创建一个委托 
   ///  
   /// 查询数据库表--------一个很耗时的方法 
   ///  
   ///  
   ///  
   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吧!


该文章在 2021/2/21 17:13:23 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved