如何停止backgroundwork
展开全部
主要做法有以下两种:
1. 多线程操作,对线程进行定时,如果超时则停止。这个机制微软给出了BackgroundWorker,但是不够灵活不建议使用。优点是足够灵活,代码比较优雅。
private void DoQuery()
{
//Query work
}
private void start()
{
Thread th = new Thread(new ThreadStart(this.DoQuery));
th.Start();
DateTime dt1 = DateTime.Now;
While(th.ThreadState != ThreadState.Stopped)
{
if((DateTime.Now-dt1).Seconds>5)
{
try
{
th.Abort();
}
catch
{
}
break;
}
Application.DoEvent();
}
}
2. 使用数据库查询的超时,不过不是楼上说道的ConnectionTimeout而是Query的CommandTimeout,可以在SqlCommand中设置。建议使用这个(不过一定不要忘记捕捉异常)!
如果是SQL Server的话:
SqlCommand comm = new comm(sql,con);
comm.CommandTimeout = 3;
try
{
comm.ExecuteNonQuery():
}
catch
{
Console.WriteLine("TimeOut");
}
}
Ps:如果是linq的话,在DataContext中有CommandTimeout属性,设置这个就可以控制SubmitChanges的超时时间。其他的关于异常捕捉的做法和上面的一样。
1. 多线程操作,对线程进行定时,如果超时则停止。这个机制微软给出了BackgroundWorker,但是不够灵活不建议使用。优点是足够灵活,代码比较优雅。
private void DoQuery()
{
//Query work
}
private void start()
{
Thread th = new Thread(new ThreadStart(this.DoQuery));
th.Start();
DateTime dt1 = DateTime.Now;
While(th.ThreadState != ThreadState.Stopped)
{
if((DateTime.Now-dt1).Seconds>5)
{
try
{
th.Abort();
}
catch
{
}
break;
}
Application.DoEvent();
}
}
2. 使用数据库查询的超时,不过不是楼上说道的ConnectionTimeout而是Query的CommandTimeout,可以在SqlCommand中设置。建议使用这个(不过一定不要忘记捕捉异常)!
如果是SQL Server的话:
SqlCommand comm = new comm(sql,con);
comm.CommandTimeout = 3;
try
{
comm.ExecuteNonQuery():
}
catch
{
Console.WriteLine("TimeOut");
}
}
Ps:如果是linq的话,在DataContext中有CommandTimeout属性,设置这个就可以控制SubmitChanges的超时时间。其他的关于异常捕捉的做法和上面的一样。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐于2016-10-11 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
向TA提问 私信TA
知道合伙人数码行家
采纳数:117538
获赞数:517184
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。
向TA提问 私信TA
关注
展开全部
BackgroundWorker 在执行DoWork事件时该如何取消呢?
方法1 DoWork 执行一个(耗时)循环
方法2 DoWork执行一个(耗时)方法[注:方法没有循环]
见代码:
方法1中DoWork事件执行的是一个for循环(foreach,while.....)
取消操作很简单,只要在循环中判断即可
看代码---------代码是从网上拷贝下来的,这种例子网上很多
view plain
#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事件中执行的是一个比较耗时的方法时该怎么办了.方法中没有循环无法判断用户是否执行了取消操作!
那么这里就要用到[异步编程模式],在执行一个比较耗时的方法时,代码还能继续向下运行.....!
请看下面代码-----------此代码是本人自己写的
view plain
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);
//开始异步执行(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;
}
}
}
方法1 DoWork 执行一个(耗时)循环
方法2 DoWork执行一个(耗时)方法[注:方法没有循环]
见代码:
方法1中DoWork事件执行的是一个for循环(foreach,while.....)
取消操作很简单,只要在循环中判断即可
看代码---------代码是从网上拷贝下来的,这种例子网上很多
view plain
#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事件中执行的是一个比较耗时的方法时该怎么办了.方法中没有循环无法判断用户是否执行了取消操作!
那么这里就要用到[异步编程模式],在执行一个比较耗时的方法时,代码还能继续向下运行.....!
请看下面代码-----------此代码是本人自己写的
view plain
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);
//开始异步执行(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;
}
}
}
本回答被提问者和网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询