这个问题之前已经被问过here ,但答案只是“使用BackgroundWorker”,我问是否有完整的代码示例可用。
我想创建一个与计时器一起使用的标准AutocompleteTextBox,这样只有一个BackgroundWorker在进行搜索 - 如果用户输入了更多的击键,但旧的搜索仍在运行 - 该搜索应该是优雅地取消(通过 CancelAsync),一旦取消,新的搜索就会开始。
实现起来并不是那么简单 - 有这方面的代码示例吗?
最佳答案
我怀疑您会找到一个代码示例来帮助您解决您在这里讨论的具体问题。我就是这样做的。这些代码都没有经过测试,所以要小心愚蠢的错误。
首先,子类 TextBoxBase
并添加两个基本方法来实现搜索逻辑,其签名如下:
private IEnumerable<string> PerformSearch(string text)
private DisplayResults(IEnumerable<string> results)
向该类添加一个名为 Worker
的私有(private) BackgroundWorker
字段,并将其 DoWork
和 RunWorkerCompleted
事件设置为 event名为 Worker_DoWork
和 Worker.RunWorkerCompleted
的处理程序。
覆盖OnTextChanged
:
public override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
// if we're already cancelling a search, there's nothing more to do until
// the cancellation is complete.
if (Worker.CancellationPending)
{
return;
}
// if there's a search in progress, cancel it.
if (Worker.IsBusy)
{
Worker.CancelAsync();
return;
}
// there's no search in progress, so begin one using the current value
// of the Text property.
Worker.RunWorkerAsync(Text);
}
Worker_DoWork
事件处理程序非常简单:
private void Worker_DoWork(object sender,
RunWorkerCompletedEventArgs e)
{
e.Result = PerformSearch((string) e.Argument);
}
Worker_RunWorkerCompleted
事件处理程序如下所示:
private void Worker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
// always check e.Error first, in case PerformSearch threw an exception.
if (e.Error != null)
{
// in your version, you want to do real exception handling, not this.
throw e.Error.InnerException;
}
// if the worker was cancelled, it's because the user typed some more text, and
// we want to launch a new search using what's currently in the Text property.
if (e.Cancelled)
{
Worker.RunWorkerAsync(Text);
return;
}
// if the worker wasn't cancelled, e.Result contains the results of the search.
DisplayResults((IEnumerable<string> e.Result);
}
请注意,DisplayResults
应测试它对文本框状态所做的任何假设。例如,当用户启动搜索时,文本框可能已经可见或启用,但现在不可见或启用。如果您在模式对话框中使用此文本框并且用户在搜索运行时取消该对话框,会发生什么情况?
另请注意,如果您的应用程序中有此控件的多个实例,则每个实例都将具有不同的 BackgroundWorker
,因此 PerformSearch
方法必须是线程化的,这一点很重要安全的。如果不是,它将必须实现锁定,这样,如果您在一个文本框中启动搜索,它会阻止并等待另一个文本框当前正在使用共享资源。
关于c# - 仅使用单个搜索BackgroundWorker的自动完成文本框 - 代码示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4705808/