#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
выполняете задачу, это исключение повторно выбрасывается в поток, который его ожидает. Он также разворачивает совокупное исключение и повторно помещает в него первое исключение.