Подтвердить что ты не робот

Отладчик не прерывает/останавливает исключения для метода async

Когда отладчик подключен к процессу .NET, он (обычно) останавливается, когда генерируется необработанное исключение.

Однако это не работает, если вы используете метод async.

Сценарии, которые я пробовал раньше, перечислены в следующем коде:

class Program
{
    static void Main()
    {
        // Debugger stopps correctly
        Task.Run(() => SyncOp());

        // Debugger doesn't stop
        Task.Run(async () => SyncOp());

        // Debugger doesn't stop
        Task.Run((Func<Task>)AsyncTaskOp);

        // Debugger stops on "Wait()" with "AggregateException"
        Task.Run(() => AsyncTaskOp().Wait());

        // Throws "Exceptions was unhandled by user code" on "await"
        Task.Run(() => AsyncVoidOp());

        Thread.Sleep(2000);
    }

    static void SyncOp()
    {
        throw new Exception("Exception in sync method");
    }

    async static void AsyncVoidOp()
    {
        await AsyncTaskOp();
    }

    async static Task AsyncTaskOp()
    {
        await Task.Delay(300);
        throw new Exception("Exception in async method");
    }
}

Я что-то упустил? Как заставить отладчик прерывать/останавливать исключение в AsyncTaskOp()?

4b9b3361

Ответ 1

В меню Debug выберите Exceptions.... В диалоговом окне "Исключения" рядом с строкой Common Language Runtime Exceptions установите флажок Thrown.

Ответ 2

Хотелось бы узнать, узнал ли кто-нибудь, как обойти эту проблему? Возможно, установка в последней визуальной студии...?

Отвратительное, но работоспособное решение (в моем случае) заключалось в том, чтобы бросить мое собственное исключение и затем изменить ответ Стивена Клири:

В меню "Отладка" выберите "Исключения" (вы можете использовать этот ярлык "Клавиатура" Control + Alt + E)... В диалоговом окне "Исключения" рядом с строкой "Исходные условия выполнения обычного языка" проверьте "Брошенный" коробка.

чтобы быть более конкретным, т.е. добавить свое пользовательское исключение в список, а затем пометить его "Брошенный".

например:

async static Task AsyncTaskOp()
{
    await Task.Delay(300);
    throw new MyCustomException("Exception in async method");
}

Ответ 3

Я обернул анонимный делегат в try/catch внутри Task.Run(() =>.

Task.Run(() => 
{
     try
     {
          SyncOp());
     }
     catch (Exception ex)
     {
          throw;  // <--- Put your debugger break point here. 
                  // You can also add the exception to a common collection of exceptions found inside the threads so you can weed through them for logging
     }

});