Обрабатывать исключение ожидание

#c# #exception #async-await

#c# #исключение #асинхронный-ожидание

Вопрос:

У меня есть следующий код:

 try
{
     await Task.Run(() => myAppClient.CreateResourceRecord());
}
catch (MyApplicationException dnsException)
{
   // Exception code
}
  

Выдается MyApplicationException во myAppClient.CreateResourceRecord() время, но не перехватывается в операторе catch (MyApplicationException dnsException).
Как это можно решить?

Комментарии:

1. Я не уверен, что эта функция действительно выдает это исключение. Вероятно, вы неправильно интерпретируете то, что видите. Опубликовать CreateResourceRecord.

2. @usr — я не могу опубликовать код. Я проверил в отладчике, что генерируется исключение MyApplicationException

3. Затем создайте repro ( throw new MyApplicationException(); ). Вы обнаружите, что не можете создать репро, потому что ваша интерпретация была просто неправильной.

4. Взгляните на msdn.microsoft.com/en-us/library/dd537614 (v = против 110).aspx … Задача переносит исключения в AggregateException

5. @MarkoDevcic и await разворачивает его.

Ответ №1:

На основе комментариев @usr:

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

 class Program
{
    static void Main(string[] args)
    {
        var t = foo();
        t.Wait();
        Console.ReadKey();
    }

    class MyApplicationException : Exception { }

    static async Task foo()
    {
        try
        {
            await Task.Run(() => { throw new MyApplicationException(); });
            Console.WriteLine("Completed without exception");
        }
        catch (MyApplicationException)
        {
            Console.WriteLine("Exception caught");
        }
    }
}
  

Вывод:

Поймано исключение

Смотрите: http://dotnetpad.net/ViewPaste/dJQgaYiqtEqqGTCiZJjdgw

Комментарии:

1. Учитывая информацию в вопросе, это, по сути, лучший ответ, который можно дать.

Ответ №2:

Помните, что Task это работает в другом потоке, поэтому исключение также генерируется в другом потоке. Чтобы перехватить исключение из Task попробуйте что-то вроде этого:

 try
{
    await Task.Run(() => myAppClient.CreateResourceRecord());
}
catch (AggregateException ae)
{
    ae.Handle((x) =>
    {
        if (x is MyApplicationException)
        {
            // Exception code
        }
    });
}
  

Комментарии:

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