【问题标题】:Cancelling long-running tasks in PLINQ在 PLINQ 中取消长时间运行的任务
【发布时间】:2010-07-19 22:29:35
【问题描述】:

我正在尝试使用 NET 4.0 并行任务库来处理多个 FTS 查询。如果查询花费了太多时间,我想取消它并继续处理其余的。

当一个查询超过阈值时,此代码不会停止。我想我这样称呼它是为了整个过程而不是单个事务达到取消任务和时间限制。如果我将时间段设置得非常小(300 毫秒),那么所有搜索字符串都会调用它。

我认为我遗漏了一些明显的东西 .. 提前感谢您的任何见解。

此外,这似乎仍然无法阻止非常长的查询执行。这甚至是在触发长时间运行的查询后取消它的正确方法吗?

修改代码:

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

var query = searchString.Values.Select(c =>myLongQuery(c)).AsParallel().AsOrdered()
                                        .Skip(counter * numToProcess).Take(numToProcess).WithCancellation(cts.Token);

  new Thread(() =>
  {
     Thread.Sleep(5000);
     cts.Cancel();
  }).Start();

  try
  {
     List<List<Threads>> results = query.ToList();
     foreach (List<Threads> threads in results)
     {
           // does something with data
     }
  } catch (OperationCanceledException) {
     Console.WriteLine("query took too long");
  }   

【问题讨论】:

  • 也许我解析错误,但似乎你的并行化太低 - 你想(如果我理解代码)在调用代码中进行并行化,所以你'正在并行运行 X 个不同的 getSearchResults 调用,而不是在 getSearchResults 方法中执行它,因为您在(可能是串行的)myLongSearchQuery 操作之后尝试 AsParallel
  • 我将我的并行性提升到了链上.. 但是长查询仍然没有被取消。这不应该在概念上起作用吗?
  • 当你取消当前正在运行的线程时允许终止,取消只是停止新线程的启动。

标签: c# timeout plinq task-parallel-library full-text-search


【解决方案1】:

PLINQ 将在每个元素数量后轮询取消标记。如果您的应用程序的检查频率不足,请确保 PLINQ 查询中所有昂贵的委托定期调用 cts.Token.ThrowIfCancellationRequested()。

更多详情请看这篇文章:http://blogs.msdn.com/b/pfxteam/archive/2009/06/22/9791840.aspx

【讨论】:

    【解决方案2】:

    这只是一个猜测:问题是不是因为查询是惰性的(就像在普通 LINQ 中一样),所以直到稍后才会执行?

    【讨论】:

    • 不确定我理解你的意思..因为没有输入结果?你能澄清一下吗?
    • 我认为var results = … 行实际上不会执行查询。只有当你实际枚举结果时才会执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多