Stu*_*ens 60 .net c# backgroundworker winforms
我有一个有2个组合框的表格.我想combobox2.DataSource基于combobox1.Text和填充combobox2.Text(我假设用户已完成输入combobox1并且正在输入中combobox2).所以我有一个这样的事件处理程序combobox2:
private void combobox2_TextChanged(object sender, EventArgs e)
{
if (cmbDataSourceExtractor.IsBusy)
cmbDataSourceExtractor.CancelAsync();
var filledComboboxValues = new FilledComboboxValues{ V1 = combobox1.Text,
V2 = combobox2.Text};
cmbDataSourceExtractor.RunWorkerAsync(filledComboboxValues );
}
Run Code Online (Sandbox Code Playgroud)
至于构建DataSource是一个耗时的过程(它创建一个对数据库的请求并执行它)我决定使用BackgroundWorker在另一个进程中执行它更好.因此,当cmbDataSourceExtractor尚未完成其工作并且用户再键入一个符号时,会出现这种情况.在这种情况下,我在这一行上得到一个例外,
cmbDataSourceExtractor.RunWorkerAsync(filledComboboxValues );说明BackgroundWorker正忙,无法同时执行多个操作.
如何摆脱这种异常?
提前致谢!
Hac*_*ese 91
CancelAsync实际上并没有中止你的线程或类似的东西.它向工作线程发送一条消息,告知应该取消工作BackgroundWorker.CancellationPending.您在后台运行的DoWork委托必须定期检查此属性并自行处理取消.
棘手的部分是您的DoWork委托可能是阻塞的,这意味着您在DataSource上所做的工作必须先完成,然后才能执行其他操作(例如检查CancellationPending).您可能需要将您的实际工作移动到另一个异步委托(或者更好的是,将工作提交给ThreadPool),并让您的主工作线程轮询,直到此内部工作线程触发等待状态,或者它检测到CancellationPending.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync.aspx
http://www.codeproject.com/KB/cpp/BackgroundWorker_Threads.aspx
jen*_*ild 30
如果你在CancelAsync()和RunWorkerAsync()之间添加一个循环,这样就可以解决你的问题
private void combobox2_TextChanged(object sender, EventArgs e)
{
if (cmbDataSourceExtractor.IsBusy)
cmbDataSourceExtractor.CancelAsync();
while(cmbDataSourceExtractor.IsBusy)
Application.DoEvents();
var filledComboboxValues = new FilledComboboxValues{ V1 = combobox1.Text,
V2 = combobox2.Text};
cmbDataSourceExtractor.RunWorkerAsync(filledComboboxValues );
}
Run Code Online (Sandbox Code Playgroud)
调用Application.DoEvents()的while循环将导致新工作线程的执行,直到当前的线程正确取消,请记住,您仍然需要处理工作线程的取消.有类似的东西:
private void cmbDataSourceExtractor_DoWork(object sender, DoWorkEventArgs e)
{
if (this.cmbDataSourceExtractor.CancellationPending)
{
e.Cancel = true;
return;
}
// do stuff...
}
Run Code Online (Sandbox Code Playgroud)
第一个代码片段中的Application.DoEvents()将继续处理您的GUI线程消息队列,因此仍然会处理取消和更新cmbDataSourceExtractor.IsBusy属性的偶数(如果您只是添加了一个continue而不是Application.DoEvents()循环会将GUI线程锁定为忙状态,并且不会处理事件以更新cmbDataSourceExtractor.IsBusy)
您必须使用主线程和BackgroundWorker之间共享的标志,例如BackgroundWorker.CancellationPending.如果希望BackgroundWorker退出,只需使用BackgroundWorker.CancelAsync()设置标志.
MSDN有一个示例:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancellationpending.aspx
| 归档时间: |
|
| 查看次数: |
176854 次 |
| 最近记录: |