假设您有一个搜索文本框,并附加了一个在TextChanged事件下运行的搜索算法,该算法使用BackgroundWorker。如果文本框中出现新字符,则需要取消先前的搜索并重新运行。
我尝试在主线程和bgw之间使用事件(参见this previous question),但仍然会出现“当前正忙,无法同时运行多个任务”的错误。
我尝试在主线程和bgw之间使用事件(参见this previous question),但仍然会出现“当前正忙,无法同时运行多个任务”的错误。
BackgroundWorker bgw_Search = new BackgroundWorker();
bgw_Search.DoWork += new DoWorkEventHandler(bgw_Search_DoWork);
private AutoResetEvent _resetEvent = new AutoResetEvent(false);
private void txtSearch_TextChanged(object sender, EventArgs e)
{
SearchWithBgw();
}
private void SearchWithBgw()
{
// cancel previous search
if (bgw_Search.IsBusy)
{
bgw_Search.CancelAsync();
// wait for the bgw to finish, so it can be reused.
_resetEvent.WaitOne(); // will block until _resetEvent.Set() call made
}
// start new search
bgw_Search.RunWorkerAsync(); // error "cannot run multiple tasks concurrently"
}
void bgw_Search_DoWork(object sender, DoWorkEventArgs e)
{
Search(txtSearch.Text, e);
}
private void Search(string aQuery, DoWorkEventArgs e)
{
int i = 1;
while (i < 3) // simulating search processing...
{
Thread.Sleep(1000);
i++;
if (bgw_Search.CancellationPending)
{
_resetEvent.Set(); // signal that worker is done
e.Cancel = true;
return;
}
}
}
为了反映答案,请不要重复使用BackgroundWorker,创建一个新的:
private void SearchWithBgw()
{
if (bgw_Search.IsBusy)
{
bgw_Search.CancelAsync();
_resetEvent.WaitOne(); // will block until _resetEvent.Set() call made
bgw_Search = new BackgroundWorker();
bgw_Search.WorkerSupportsCancellation = true;
bgw_Search.DoWork += new DoWorkEventHandler(bgw_Search_DoWork);
}
bgw_Search.RunWorkerAsync();
}
new BackgroundWorker()
,我该如何取消之前的工作?我应该将工作线程保存在列表中吗?由于搜索功能会更新控件,我不希望多个工作线程更新同一个控件。 - Carlos Torres