13

When you turn on the "Break when an exception is thrown" feature in the Visual Studio debugger it breaks everywhere for selected exception types. The way to tell it not to break in a specific method is to decorate these methods with DebuggerStepThrough attribute (or DebuggerHidden).

This, evidently, doesn't work for an async method for some reason. Here's a snippet that reproduces the issue. The debugger will break inside the TestAsync even though it's marked with the attributes and it will not break inside Test as excepted ( the only difference between them is the first is marked with the async keyword):

public class Attributes
{
    public async Task Run()
    {
        await TestAsync();
        await Test();
    }

    [DebuggerHidden]
    [DebuggerStepThrough]
    public async Task TestAsync()
    {
        try
        {
            throw new Exception("Async");
        }
        catch
        {
        }
        await Task.Delay(100);
    }

    [DebuggerHidden]
    [DebuggerStepThrough]
    public Task Test()
    {
        try
        {
            throw new Exception("sync");
        }
        catch
        {
        }
        return Task.Delay(100);
    }
}

So, is this behavior intended? Is it a bug? Is there a workaround?

Community
  • 1
  • 1
i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • 2
    It is a fairly inevitable flaw in the way the C# compiler implements asynch, your method is *rewritten* into a hidden class. Which does not get those same attributes. Use ildasm.exe to look under the hood. – Hans Passant Jun 26 '14 at 14:53
  • @HansPassant I originally thought it doesn't work only after an await is used (ie the continuation), but apparently it always fails. – i3arnon Jun 26 '14 at 14:55

1 Answers1

5

Attributes don't play well with async/await since async methods get re-written under the covers--and the attributes do not follow. See https://stackoverflow.com/a/22412597/495262 for a similar situation.

Community
  • 1
  • 1
Matt Smith
  • 17,026
  • 7
  • 53
  • 103
  • 1
    Note that `DebuggerStepThrough` and `DebuggerHidden` are subject to interpretation by a particular debugger. They have no particular meaning to the CLR. They may well work as documented in future updates of VS. – Eric J. Jul 14 '14 at 21:46