在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
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); //创建一个委托 /// <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 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); //创建一个委托 /// <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吧! |
请发表评论