【问题标题】:Unhandled OperationCanceledException when thrown from Parallel.ForEach从 Parallel.ForEach 抛出未处理的 OperationCanceledException
【发布时间】:2012-09-15 11:03:20
【问题描述】:

我正在尝试允许取消 Parallel.ForEach 循环。根据this MSDN article的说法是有可能的,我正在关注他们的编码。

// Tokens for cancellation 
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;

try
{
    Parallel.ForEach(queries, po, (currentQuery) =>
    {
        // Execute query
        ExecuteQuery(currentQuery);

        // Throw exception if cancelled 
        po.CancellationToken.ThrowIfCancellationRequested(); // ***
    }); 
}
catch (OperationCanceledException cancelException)
{
    Console.WriteLine(cancelException.Message);
}

但是,当我从用户可访问的函数中调用 cts.Cancel(); 时,应用程序在上面标有星号的行上崩溃并出现错误:

System.OperationCanceledException was unhandled by user code
  Message=The operation was canceled.
  Source=mscorlib
  StackTrace:
   at System.Threading.CancellationToken.ThrowIfCancellationRequested()
   at CraigslistReader.SearchObject.<>c__DisplayClass7.<bw_DoWork>b__5(Query currentQuery) in {PATH}:line 286
   at System.Threading.Tasks.Parallel.<>c__DisplayClass2d`2.<ForEachWorker>b__23(Int32 i)
   at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c()
InnerException: 

我有异常处理程序,所以我不理解崩溃。有什么想法吗?

【问题讨论】:

  • 我没有看到您描述的问题,catch 对我来说很好用。您能否发布一个完整但简短的代码来显示您的问题?
  • 我认为应用程序没有崩溃,至少没有这个例外。要么你的应用没有崩溃(你怎么知道它已经崩溃了?),或者这不是最后一个发生的异常。
  • @usr 是的,你是对的。我在调试器中运行它,当我看到异常停止运行时,我认为这是一个会使应用程序崩溃的异常。我不知道有些异常不会导致崩溃。
  • 我相信这通常被称为第一次机会例外。正如您所注意到的,这并不意味着它会使应用程序崩溃,而只是一个调试概念。

标签: c# wpf exception-handling parallel.foreach


【解决方案1】:

问题在于po.CancellationToken.ThrowIfCancellationRequested(); 明确抛出了一个未处理的异常。异常处理程序可能在 Parrallel.ForEach() 调用附近,但异常不在 lambda 表达式中处理。删除该行或在 lambda 表达式中添加一个异常处理程序,它应该可以工作。

更多信息请参见Cancelling a Task is throwing an exception

【讨论】:

  • @svick 可能。看看我链接的答案并尝试它的建议。如果它有效,它就有效。
  • @akton:我尝试将 try/catch 放在 Lamba 表达式中,但仍然会导致运行时错误。
  • @Doug 嗯。我会继续挖掘,如果我找到任何东西,我会告诉你。提出问题,看看是否有其他人知道
  • @akton 我能够通过在 lambda 表达式中使用 try/catch 并将 Parallel.ForEach 包装在 try/catch 中来解决此问题。不知道为什么我必须同时做这两件事。
  • @publicENEMY 对ThrowIfCancellationRequested() 的调用进行尝试/捕获。
猜你喜欢
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多