C# 如何取消BackgroundWorker異步操作
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
BackgroundWorker 在執(zhí)行DoWork事件時(shí)該如何取消呢? 方法1 DoWork 執(zhí)行一個(gè)(耗時(shí))循環(huán) 方法2 DoWork執(zhí)行一個(gè)(耗時(shí))方法[注:方法沒有循環(huán)] 見代碼: 方法1中DoWork事件執(zhí)行的是一個(gè)for循環(huán)(foreach,while.....) 取消操作很簡單,只要在循環(huán)中判斷即可 看代碼---------代碼是從網(wǎng)上拷貝下來的,這種例子網(wǎng)上很多 #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 傳過來的參數(shù) }
} static void bw_ProgressChanged(object
sender, ProgressChangedEventArgs e) {
Console.Write("{0,3}/b/b/b", e.ProgressPercentage); } } }
#endregion
如果方法2中DoWork事件中執(zhí)行的是一個(gè)比較耗時(shí)的方法時(shí)該怎么辦了?方法中沒有循環(huán)無法判斷用戶是否執(zhí)行了取消操作! 那么這里就要用到[異步編程模式],在執(zhí)行一個(gè)比較耗時(shí)的方法時(shí),代碼還能繼續(xù)向下運(yùn)行.....! 請看下面代碼: BackgroundWorker bgworker = new BackgroundWorker(); gworker.WorkerSupportsCancellation = true; //是否支持異步取消 如果要取消操作必須設(shè)置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) //是否在運(yùn)行異步操作 { bgworker.CancelAsync(); //(是)提交取消命令 } } private void bgworker_DoWork(object sender, DoWorkEventArgs e) { //Sql語句 查詢的數(shù)據(jù)很多 string sql = "select * from table"; //綁定委托要執(zhí)行的方法 Del_DoWork work = new Del_DoWork(ReturnDataTable); //可以使用:delegate、Action、Func、predicate 等,具體可參考:C#委托的介紹(delegate、Action、Func、predicate) 和 委托的N種寫法 //開始異步執(zhí)行(ReturnDataTable)方法 IAsyncResult ret = work.BeginInvoke(sql, null, null); //(異步編程模式好久就是在執(zhí)行一個(gè)很耗時(shí)的方法(ReturnDataTable)時(shí),還能向下繼續(xù)運(yùn)行代碼) //接著運(yùn)行下面的while循環(huán), //判斷異步操作是否完成 while (!ret.IsCompleted) { //沒完成 //判斷是否取消了backgroundworker異步操作 if (bgworker.CancellationPending) { //如何是 馬上取消backgroundwork操作(這個(gè)地方才是真正取消) e.Cancel = true; return; } } e.Result = work.EndInvoke(ret); //返回查詢結(jié)果 賦值給e.Result } private delegate DataTable Del_DoWork(string sql); //創(chuàng)建一個(gè)委托 /// /// 查詢數(shù)據(jù)庫表--------一個(gè)很耗時(shí)的方法 /// /// /// 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("出現(xiàn)錯(cuò)誤!"); } else { DataTable table = e.Result as DataTable; if (table != null) { //得到數(shù)據(jù),進(jìn)行顯示操作 //dataGridView1.DataSource = table; } } } 我這里主要是用方法2,在很多情況下,我們的DoWork事件都是執(zhí)行一個(gè)方法,而不是一個(gè)循環(huán)....,如果你也遇到要執(zhí)行一個(gè)耗時(shí)方法,又要取消操作的話,請用方法2吧! 該文章在 2021/2/21 17:13:23 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |