AggregateException during debugging forces restart of ForAll body

228 views Asked by At

I'm experiencing really strange behavior, which I cannot neither understand nor explain. I was able to create a really simple sample to demonstrate that. That was reproduced on VS.Net 2013 & 2015 on different machines with several target .Net versions.

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();
            });
        }
    }
}

When you just run that code without debugging, you receive what expected: two task started, one failed, and AggregateException details in console:

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
...

But when you start the same code with debugging, results are really weird. First, you receive AggregateException:

VS.2013 AggregateException

But when you click Continue, it just starts both tasks again and again - here is sample output from Console:

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

I was using two tasks to demonstrate that they are both restarting; you can comment out empty one and receive the same confusing results.

My question here - is this a VS.Net bug, or some feature I don't understand?

Is there a way to debug in a "normal" way here?

1

There are 1 answers

3
Jack Zhai On

I can repro this issue in my side, the real issue is that the whole .exe/program was not exited like the messages we often get if a console app was exited:

The program '[xxx] ConsoleApplication12.vshost.exe' has exited with code 0 (0x0).

To really reprove it, for example, not really debug your app using the F5, just debug your app using the F11(Step Into)(Debug app one step by one step), you would find that the app couldn't be exited after the second exception showed.

Another way to prove it is that you could add try...catch in following code:

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

And then debug your app again, you would find that it would not output the messages again by again and the app was exited even if it still has the first exception enter image description here

Update: I just find that one debug option really impacts the issue. If I disable this option, it would not debug the app again by again after I click "Break" or "Continue" in that pop window.

enter image description here