调试期间的AggregateException强制重新启动ForAll正文

时间:2016-12-26 06:01:44

标签: c# visual-studio debugging plinq aggregateexception

我正在经历一种非常奇怪的行为,我既不理解也不解释。我能够创建一个非常简单的样本来证明这一点。这是在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:

VS.2013 AggregateException

但是当你点击继续时,它只是一次又一次地启动这两个任务 - 这是来自Console的示例输出:

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

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

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

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

1 个答案:

答案 0 :(得分:0)

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

该程序&#39; [xxx] ConsoleApplication12.vshost.exe&#39;已退出代码0(0x0)。

要真正责备它,例如,不要使用F5调试你的应用程序,只需使用F11调试你的应用程序(Step Into)(调试应用程序一步一步),你会发现应用程序无法&#39 ;在第二个例外显示后退出。

证明它的另一种方法是你可以在下面的代码中添加try ... catch:

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

然后再次调试你的应用程序,你会发现它不会再次输出消息,即使它仍然有第一个例外,应用程序也会退出 enter image description here

更新:我发现一个调试选项确实会影响这个问题。 如果我禁用此选项,则在点击&#34; Break&#34;之后,它将不会再次调试应用程序。或者&#34;继续&#34;在那个弹出窗口中。

enter image description here