Onl*_*ere 0 c# wpf backgroundworker
我正在尝试在WPF应用程序中使用后台工作程序.繁重的任务使用WebClient下载一些HTML并从中解析一些信息.理想情况下,我希望在不锁定UI的情况下进行下载和解析,并在完成工作后将结果放入UI中.
它运行正常,但是,如果我快速提交"下载和解析"命令,我会收到错误:
此BackgroundWorker当前正忙,无法同时运行多个任务
所以我做了一些谷歌搜索,似乎我可以启用.WorkerSupportsCancellation后台工作者的属性,只是.CancelAsync().但是,这不能按预期工作(取消当前的下载和解析).
我仍然得到上述错误.
这是我的代码:
//In window constructor.
_backgroundWorker.WorkerSupportsCancellation = true;
_backgroundWorker.DoWork += new DoWorkEventHandler(_backgroundWorker_DoWork);
_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted);
//Declared at class level variable.
BackgroundWorker _backgroundWorker = new BackgroundWorker();
//This is the method I call from my UI.
private void LoadHtmlAndParse(string foobar)
{
//Cancel whatever it is you're doing!
_backgroundWorker.CancelAsync();
//And start doing this immediately!
_backgroundWorker.RunWorkerAsync(foobar);
}
POCOClassFoo foo = new POCOClassFoo();
void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//This automagically sets the UI to the data.
Foo.DataContext = foo;
}
void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
//DOING THE HEAVY LIFTING HERE!
foo = parseanddownloadresult()!
}
Run Code Online (Sandbox Code Playgroud)
通话CancelAsync仍然会激活此RunWorkerCompleted事件.在这种情况下,您需要CancelAsync通过检查确保尚未调用e.Cancelled.在此事件发生之前,您无法致电RunWorkerAsync.
或者,我建议你做Tigran建议的,BackgroundWorker每次创建一个新的.
此外,我建议存储_backgroundWorker_DoWorkin 的结果e.Result,然后从中检索它们_backgroundWorker_RunWorkerCompleted
也许这样的事情
BackgroundWorker _backgroundWorker;
private BackgroundWorker CreateBackgroundWorker()
{
var bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.DoWork += _backgroundWorker_DoWork;
bw.RunWorkerCompleted += new _backgroundWorker_RunWorkerCompleted;
return bw.
}
private void LoadHtmlAndParse(string foobar)
{
//Cancel whatever it is you're doing!
if (_backgroundWorer != null)
{
_backgroundWorker.CancelAsync();
}
_backgroundWorker = CreateBackgroundWorker();
//And start doing this immediately!
_backgroundWorker.RunWorkerAsync(foobar);
}
//you no longer need this because the value is being stored in e.Result
//POCOClassFoo foo = new POCOClassFoo();
private void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
//Error handling goes here.
}
else
{
if (e.Cancelled)
{
//handle cancels here.
}
{
//This automagically sets the UI to the data.
Foo.DataContext = (POCOClassFoo)e.Result;
}
}
private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
//DOING THE HEAVY LIFTING HERE!
e.Result = parseanddownloadresult()!
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14536 次 |
| 最近记录: |