Bre*_*Dev 7 c# multithreading process backgroundworker
我遇到了一个我不确定如何解决的问题.我有一个方法,其中包含来自填充数据表的服务的调用,例如:
private void GetCases()
{
try
{
//Setup our criteria
Web_search_criteria myCriteria = new Web_search_criteria()
{
Keynum = 9, //Use Opening Date Key
Range_start = "20100101", //01-01-2010
Range_end = "20121223" //12-23-2013
};
//The myCases object is a datatable that is populated from the GetCasesDT() call.
int status = db.server.GetCasesDT(myCriteria, ref myCases);
}
catch (Exception ex)
{
XtraMessageBox.Show("Unable to get data: " + ex.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
所以,正如你所看到的,我没有办法一次抓住几个案例 - 它只是抓住了一切.
现在,我在BackgroundWorker的DoWork事件中调用了这个方法,并在其上显示另一个带有选取框进度条的表单,以便用户知道系统实际上正在执行某些操作.在那个表单上,我有一个我订阅的取消按钮.这是执行此操作的代码:
backgroundWorker1 = new BackgroundWorker()
{
WorkerSupportsCancellation = true,
WorkerReportsProgress = true
};
//DoWork Event
backgroundWorker1.DoWork += backgroundWorker1_DoWork;
//Show the progress bar with subscription to event
pb.btnCancel.Click += this.CancelBW;
pb.Show();
//Run the backgroundworker
this.backgroundWorker1.RunWorkerAsync();
//Don't lock up the application
while (this.backgroundWorker1.IsBusy)
{
Application.DoEvents();
}
Run Code Online (Sandbox Code Playgroud)
我试图通过使用CancelAsync()取消CancelBW事件中的BackgroundWorker,但后来我读了更多并意识到这不起作用,只有在我打破初始调用以便BackgroundWorker可以检查进度时才能工作.
我曾考虑使用Thread而不是BackgroundWorker,但已经读过,中止一个线程会导致小猫自发燃烧.
那么,对我来说,处理这种情况的最佳方式是什么,用户可以取消漫长的过程?
没有根本性的方法可以正确取消此操作。这不是 CPU 密集型工作,而是网络密集型工作。您发送了请求,但无法从互联网上准确地获取该请求。您真正能做的就是在满足取消条件时让代码继续执行,而不是等待操作完成。
您的应用程序的一个主要问题是您泵送消息队列的繁忙循环:
while (this.backgroundWorker1.IsBusy)
{
Application.DoEvents();
}
Run Code Online (Sandbox Code Playgroud)
这通常是一个坏主意,是应该避免的做法。BackgroundWorker首先使用 a 的想法是让它是异步的;在 BGW 完成之前,您不应该尝试阻止当前方法。
虽然有多种方法可以将 BGW 纳入其中;这种特殊情况使用任务并行库可能更容易解决。
var cts = new CancellationTokenSource();
pb.btnCancel.Click += (s, e) => cts.Cancel();
pb.Show();
var task = Task.Factory.StartNew(() => GetCases())
.ContinueWith(t => t.Result, cts.Token)
.ContinueWith(t =>
{
//TODO do whatever you want after the operation finishes or is cancelled;
//use t.IsCanceled to see if it was canceled or not.
});
Run Code Online (Sandbox Code Playgroud)
(我还建议重构,GetCases以便它返回DataTable从数据库获取的内容,而不是修改实例字段。然后您可以通过任务的Result.
| 归档时间: |
|
| 查看次数: |
234 次 |
| 最近记录: |