0

I'm playing around with TPL and have this simple program

class Program
{
    static void Main(string[] args)
    {
        MainAsync().Wait();         
    }

    static async Task MainAsync()
    {
        try
        {
            var tcs = new TaskCompletionSource<string>();
            var canceled = tcs.TrySetCanceled();
            var myCanceledTask = tcs.Task;
            string result = "canceled";

            if (myCanceledTask.IsCanceled)
            {
                result = await myCanceledTask;
            }
            else
            {
                Console.WriteLine("Couldn't cancel task.");
            }

            Console.WriteLine("ID: \t" + myCanceledTask.Id);
            Console.WriteLine("Canceled: \t" + myCanceledTask.IsCanceled);
            Console.WriteLine("Completed: \t" + myCanceledTask.IsCompleted);
            Console.WriteLine("Faulted: \t" + myCanceledTask.IsFaulted);
            Console.WriteLine("Status: \t" + myCanceledTask.Status);
            Console.WriteLine("Result: \t" + result);
            Console.ReadLine();
        }
        catch (Exception e)
        {
            var msg = "CANCELED ERROR";
            throw new Exception(msg, e);
        }
    }
}

What's interesting to me is that, when debugging, this will loop indefinitely through exceptions on the following lines, in the following order:

result = await myCanceledTask, then on throw new Exception(msg, e), then on MainAsync().Wait(), and finally a second pause on MainAsync().Wait().

At this point I would expect the program to exit, but it appears to loop. I can just keep clicking Continue to loop through the various breaks above. Visual Studio never drops out of debugging mode.

Any idea why Visual Studio is behaving this way? If I run the program without debugging, I get an exception and can close the program, as expected.

Matt
  • 1,674
  • 2
  • 16
  • 34
  • 1
    F5 starts a new instance. Are you sure you are not just running the program multiple times? – Scott Chamberlain Apr 17 '17 at 15:00
  • Please try this link may be it will be helpful for you. [How to cancel a task in await?](http://stackoverflow.com/questions/10134310/how-to-cancel-a-task-in-await) – Prashant Tomar Apr 17 '17 at 15:36
  • @ScottChamberlain if F5 is equivalent to clicking "Continue", then this sounds like the answer. I was overthinking this one. I would expect it to fall out of debugging first, though, no? – Matt Apr 17 '17 at 16:13
  • @PrashantTomar my curiosity is not related to the task being canceled, that is behaving as expected. It's VS that behaving unexpectedely – Matt Apr 17 '17 at 16:15
  • VS will "break" on an exception depending on your exception settings. I went to Debug->Windows->Exception Settings and made sure the entire Common Language Runtime Exceptions section was checked. After that I get breaks on the same spots you do: I press F5 once to start the program, it breaks on `result =`, F5 2nd time it breaks on `throw new exception`, F5 3rd time it breaks on `MainAsync().Wait();` for the first aggregate exception, F5 4th time it breaks there again for second aggregate exception, F5 5th time and the program ends. If I hit F5 a 6th time it Starts Debugging again and "loops". – Quantic Apr 17 '17 at 18:44
  • To Scott Chamberlains point, the only way the program "loops" is if you keep hitting F5 without looking at what the program is doing because you'll just spin up the entire program again after it already exited. I copied your exact program and it ends fine after I hit F5 a certain number of times (depending on your exception settings), but if you hit F5 an extra time after it ends then it just starts again. From what we can see VS is not looping the program, you are, or you aren't showing us all the code. – Quantic Apr 17 '17 at 18:45
  • @Quantic If you are seeing the program exit then I don't know what more information to provide. I am not using F5 (manually clicking "Continue"). The program never exits (i.e. the "Continue" button never changes back to "Start") and I loop through the breaks articulated in my question. Maybe VS version? I am using VS 2015 Version 14.0.25431.01 Update 3 – Matt Apr 17 '17 at 19:03
  • It could be the VS version, I am on 2017 now and can't easily test with 2015. Does the Call Stack continue to grow if you hit `Continue` a whole bunch of times? After you start debugging you should find the window via Debug -> Windows -> Call Stack. – Quantic Apr 17 '17 at 19:28
  • Nope, it never goes deeper than Main() -> MainAsync() – Matt Apr 17 '17 at 19:37
  • 1
    Looks like I was wrong when I said "the only way it loops is when xxxx"--according to the duplicate I just flagged in VS 2015 and earlier the debugger can automatically "unwind the call stack" on an unhandled exception so it just continues forever. Note that they removed this in 2017: ["When managed debugging, the debugger will no longer automatically unwind the Call Stack"](https://blogs.msdn.microsoft.com/visualstudioalm/2016/03/31/using-the-new-exception-helper-in-visual-studio-15-preview/). – Quantic Apr 18 '17 at 16:02
  • This sounds like my solution, thank you. If you post a proper solution, I'll be sure to mark it as such. – Matt Apr 19 '17 at 21:18

0 Answers0