Ответ 1
Когда метод async
запущен, он захватывает текущий контекст синхронизации. Способ решения этой проблемы - создать собственный контекст синхронизации, который фиксирует исключение.
Дело в том, что контекст синхронизации отправляет обратный вызов в пул потоков, но с try/catch вокруг него:
public class AsyncSynchronizationContext : SynchronizationContext
{
public override void Send(SendOrPostCallback d, object state)
{
try
{
d(state);
}
catch (Exception ex)
{
// Put your exception handling logic here.
Console.WriteLine(ex.Message);
}
}
public override void Post(SendOrPostCallback d, object state)
{
try
{
d(state);
}
catch (Exception ex)
{
// Put your exception handling logic here.
Console.WriteLine(ex.Message);
}
}
}
В catch
выше вы можете поместить свою логику обработки исключений.
Далее, в каждом потоке (SynchronizationContext.Current
есть [ThreadStatic]
), где вы хотите использовать методы async
с этим механизмом, вы должны установить текущий контекст синхронизации:
SynchronizationContext.SetSynchronizationContext(new AsyncSynchronizationContext());
Полный пример Main
:
class Program
{
static void Main(string[] args)
{
SynchronizationContext.SetSynchronizationContext(new AsyncSynchronizationContext());
ExecuteAsyncMethod();
Console.ReadKey();
}
private static async void ExecuteAsyncMethod()
{
await AsyncMethod();
}
private static async Task AsyncMethod()
{
throw new Exception("Exception from async");
}
}