【问题标题】:AggregateException during debugging forces restart of ForAll body [duplicate]调试期间的 AggregateException 强制重新启动 ForAll 主体 [重复]
【发布时间】:2017-05-10 16:03:04
【问题描述】:

我遇到了非常奇怪的行为,我既无法理解也无法解释。我能够创建一个非常简单的示例来证明这一点。这是在 VS.Net 2013 和 2015 上在具有多个目标 .Net 版本的不同机器上复制的。

using System;
using System.Linq;

namespace Sample
{
    internal static class Program
    {
        private static void Main(string[] args)
        {
            ExecuteInParallel(new[]
            {
                new Tuple<string, Action>("Task1", () => { }),
                new Tuple<string, Action>("Task2", () => { throw new Exception("Exception"); })
            });
        }

        private static void ExecuteInParallel(Tuple<string, Action>[] tasks)
        {
            tasks.AsParallel().ForAll(x =>
            {
                Console.WriteLine("Starting " + x.Item1);
                x.Item2();
            });
        }
    }
}

当您只运行该代码而不进行调试时,您会收到预期的结果:两项任务已启动,一项失败,以及控制台中的 AggregateException 详细信息:

Starting Task1
Starting Task2

Unhandled Exception: System.AggregateException: One or more errors occurred. ---> System.Exception: Exception
   at Sample.Program.<Main>b__1() in d:\temp\ConsoleApplication40\ConsoleApplication40\Program.cs:line 13
...

但是当你开始调试相同的代码时,结果真的很奇怪。首先,您会收到 AggregateException:

但是当您单击继续时,它只会一次又一次地启动这两个任务 - 这是控制台的示例输出:

Starting Task1
Starting Task2
Starting Task1
Starting Task2
Starting Task1
Starting Task2
Starting Task1
Starting Task2

我正在使用两个任务来证明它们都在重新启动;你可以注释掉一个空的并得到同样令人困惑的结果。

我的问题是 - 这是 VS.Net 的错误,还是我不理解的某些功能?

这里有没有办法以“正常”的方式进行调试?

【问题讨论】:

  • @JackZhaiMSFT 的回答让我朝着正确的方向前进 - 看起来这就是 Unwind the callstack on unhandled exceptions 功能的工作原理。这是(不被接受但高度赞成)类似问题的答案stackoverflow.com/a/23002780/2170171voting for duplicate。

标签: c# visual-studio debugging plinq aggregateexception


【解决方案1】:

我可以在我这边重现这个问题,真正的问题是整个 .exe/程序没有像退出控制台应用程序时经常收到的消息那样退出:

程序“[xxx] ConsoleApplication12.vshost.exe”已退出,代码为 0 (0x0)。

要真正反驳它,例如,不真正使用F5调试您的应用,只需使用F11(Step Into)(一步一步调试应用)调试您的应用,您会发现该应用无法在出现第二个异常后退出。

另一种证明方法是,您可以在以下代码中添加 try...catch:

          tasks.AsParallel().ForAll(x =>
            {
                Console.WriteLine("Starting " + x.Item1);
                x.Item2();
            });

然后再次调试你的应用程序,你会发现它不会再次输出消息并且应用程序退出了,即使它仍然有第一个异常

更新:我只是发现一个调试选项确实会影响问题。 如果我禁用此选项,则在该弹出窗口中单击“中断”或“继续”后,它将不会再次调试应用程序。

【讨论】:

  • 虽然您证明确实存在问题,但我不明白这如何回答问题。对我来说,“程序未退出”只是奇怪的调试器行为的结果
  • 谢谢,这个答案让我朝着正确的方向前进 - 请参阅我对上述问题的评论。
  • @Lanorkin,感谢您在这里分享您的有用信息,此问题与您提供的链接相似,但您不必编辑此问题作为重复项,因为不同的成员提出了此问题并且它没有标记答案。如果您接受它作为答案,如果可能的话,您可以在此处发布您的评论作为答案,这样可以帮助遇到相同问题的其他成员。不管怎样,祝你有美好的一天:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 2019-03-17
相关资源
最近更新 更多