| C# 如何取消BackgroundWorker异步操作
					当前位置:点晴教程→知识管理交流
					
					→『 技术文档交流 』
					
				 
 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); //可以使用: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); //创建一个委托 /// /// 查询数据库表--------一个很耗时的方法 /// /// /// 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 编辑过 | 关键字查询 相关文章 正在查询... |