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

Как я могу сделать VS break на исключениях в async Task, не нарушая все исключения?

Как указано здесь и здесь, исключения, возникающие в async Task, технически не обрабатываются.

Это особенно неприятно при работе с MVC. На самом деле нам потребовалось некоторое время, чтобы понять, почему все чаще и чаще происходит исключение, но мы постепенно вводили вызовы Web API в наши приложения за последние несколько недель.

public async Task<ActionResult> Foo()
{
    // ...
}

Предлагаемое обходное решение состоит в том, чтобы заставить VS нарушить все исключения вместо только необработанных исключений. Он работает с раздражающим "побочным эффектом", который действительно нарушает все исключения:)

Есть ли другое обходное решение, которое не связано с нарушением всех исключений? Это может быть специфично для MVC, но не обязательно (это означает, что это общее решение, которое работает для MVC).

4b9b3361

Ответ 1

A) Оберните свои вызовы и выбросите пользовательское исключение в свой код задачи. Перерыв только в том, что вы выбрали собственное исключение. Вы можете выбрать Исключения для первого броска.

В). Debug.Assert() ваши результаты задачи, если у вас есть код ожидания. т.е. не просто стрелять и забывать. Задачи возвращают Исключения в свойстве, если вы их где-то ждёте, или продолжите обработку ошибок.

psuedo code т.е. задача. continuewith (r = > if (! r.Exception равно null) Debug.Break())) и др.

Надеюсь, что это поможет вам на правильном пути.

Ответ 2

Вы можете попробовать и послушать это событие, если здесь ничего не работает.

AppDomain.CurrentDomain.UnhandledException

или

AppDomain.CurrentDomain.FirstChanceException

Затем вам нужно поместить некоторые if-constructs (проверьте, например, какой отправитель), чтобы попасть в точку останова только тогда, когда это имеет смысл.

Ответ 3

ссылка try-catch в MSDN содержит некоторые рекомендации и примеры исключений в асинхронных методах и гласит: "Завершенная задача, к которой await может быть в неисправном состоянии из-за необработанного исключения в методе, который возвращает задачу. Ожидание задачи вызывает исключение."

В примере, приведенном на этой странице, в нем говорится: "Следующий пример иллюстрирует обработку исключений для методов async. Чтобы поймать исключение, которое вызывает асинхронная задача, поместите выражение wait в try и поймать исключение в блоке catch. Раскомментируйте строку throw new Exception в примере, чтобы продемонстрировать обработку исключений. Свойство Исправлено установите True, свойство Исключение .InnerException установлено в исключение, и исключение попадает в блок catch.. p >

Здесь копия из приведенного здесь примера:

public async Task DoSomethingAsync()
{
    Task<string> theTask = DelayAsync();

    try
    {
        string result = await theTask;
        Debug.WriteLine("Result: " + result);
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Exception Message: " + ex.Message);
    }
    Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled);
    Debug.WriteLine("Task IsFaulted:  " + theTask.IsFaulted);
    if (theTask.Exception != null)
    {
        Debug.WriteLine("Task Exception Message: "
            + theTask.Exception.Message);
        Debug.WriteLine("Task Inner Exception Message: "
            + theTask.Exception.InnerException.Message);
    }
}

private async Task<string> DelayAsync()
{
    await Task.Delay(100);

    // Uncomment each of the following lines to 
    // demonstrate exception handling. 

    //throw new OperationCanceledException("canceled");
    //throw new Exception("Something happened.");
    return "Done";
}

// Output when no exception is thrown in the awaited method: 
//   Result: Done 
//   Task IsCanceled: False 
//   Task IsFaulted:  False 

// Output when an Exception is thrown in the awaited method: 
//   Exception Message: Something happened. 
//   Task IsCanceled: False 
//   Task IsFaulted:  True 
//   Task Exception Message: One or more errors occurred. 
//   Task Inner Exception Message: Something happened. 

// Output when a OperationCanceledException or TaskCanceledException 
// is thrown in the awaited method: 
//   Exception Message: canceled 
//   Task IsCanceled: True 
//   Task IsFaulted:  False

Ответ 4

Включение "Just My Code" - это один из способов сделать это, как предложено здесь. Правда, исключения технически не необработаны, но они необработаны по коду пользователя, который получает VS, чтобы сделать полезную вещь и показать вам, где произошло исключение.

Смотрите этот ответ для некоторых скриншотов.

Очевидно, что этот параметр имеет другие последствия (например, вы больше не можете проходить через код рамки), поэтому это может быть или не быть подходящим.

Ответ 5

Вы можете добавить обработчик для TaskScheduler.UnobservedTaskException.

Однако, возможно, вы уже пробовали это, и хотите, чтобы отладчик разбился на исходное исключение, а не на ненаблюдаемый обработчик исключения задачи.