0

我正在组合一个简单的 C# 应用程序,用户在“命令栏”中键入命令,并实时获取结果。

例如,我可以键入 , google stackoverflow,它会向 google 发送一个 API 调用,获取每个结果并将它们显示在 ui 中。

目前,如果用户在打字时暂停超过 1/4 秒,我会触发“搜索”方法,因此如果您在中间暂停,它可能会触发google stackgoogle stackoverflow.

现在实际上 api 正在执行(相当慢的)数据库查询,这会导致 ui 在第一次搜索完成时锁定,然后再尝试开始第二次搜索。

是否有一种简单的(C# 4.0)方法可以在单独的线程中运行搜索调用,如果用户继续输入,我可以取消/中止?

例如

Task<string> thread;

string getSearchResults(string input) {
    ... Do some work ...
}

string userPaused(string search) {
  if(this.thread.isRunning()) this.thread.Kill();

  this.thread = new Task<String>(getSearchResults(string input);

  return this.thread.result();
}

我查看了Tasks api,它看起来好像你不能在工作中杀死一个任务,它建议使用一段时间查看并传递一个shouldStop布尔值,但是在API调用下载结果期间没有while 循环。

但是,如果您需要获取返回值,Threading 文档会将您指向任务。

4

1 回答 1

1

您可以做的Tasks是创建它们,然后在不再需要时取消。如果您无法取消您正在执行的操作(如数据库查询) - 您始终可以在返回结果之前取消。您的代码可能是这样的(未经测试,只是草稿):

    var tokenSource2 = new CancellationTokenSource();
    CancellationToken ct = tokenSource2.Token;

    var task = Task.Factory.StartNew(() =>
    {
        ct.ThrowIfCancellationRequested();

        var result = Database.GetResult(); // whatever database query method you use.
        ct.ThrowIfCancellationRequested();
        return result;
    }, tokenSource2.Token);

所以你可以看到它会在没有取消请求时查询数据库并返回值,但是如果你试图取消任务 - 它不会返回值而是抛出OperationCanceledException你需要捕获的。有关详细信息,请访问MSDN Task Cancellation,但我认为这应该给您一个想法。不要担心大任务数 - 如果您的查询不是很慢也没关系 - 用户将无法触发如此多的搜索。如果您有查询数据库的异步方式 - 您可以进一步改进此代码,但这也不应该太难。

于 2013-05-08T11:57:01.737 回答