0

ユーザーがコマンドを「コマンド バー」に入力すると、結果がリアルタイムでフェッチされる単純な C# アプリをまとめています。

たとえば、「」と入力google stackoverflowすると、API 呼び出しが Google に送信され、各結果が取得されて UI に表示されます。

現在、ユーザーが入力中に 1/4 秒以上一時停止した場合、「検索」メソッドを起動します。そのため、途中で一時停止するgoogle stackと、google stackoverflow.

実際には、API は (かなり遅い) データベース クエリを実行しているため、最初の検索が完了している間、2 番目の検索を開始しようとする前に、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 を確認しましたが、作業中にタスクを強制終了できるようには見えません。while ルックを使用してshouldStopブール値を渡すことをお勧めしますが、API 呼び出し中に結果をダウンロードすることはありません。 while ループ。

ただし、スレッドのドキュメントでは、戻り値を取得する必要がある場合のタスクを示しています。

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 タスクのキャンセルをご覧ください。ただし、これでアイデアが得られるはずです。タスク数が多いことを心配する必要はありません。クエリがそれほど遅くなければ問題ありません。ユーザーはそれほど多くの検索をトリガーすることはできません。データベースにクエリを実行する非同期の方法がある場合は、このコードをもう少し改善できますが、それほど難しくはありません。

于 2013-05-08T11:57:01.737 に答える