Необработанное исключение типа "System.AggregateException" в System.Private.CoreLib.dll
Как обработать это исключение ? мой catch
его не ловит)
Использую MySQL.Data
Всё что взаимодействует с MySQL.Data
всё находится в try
и не упущен никакой await
.
Но всё равно, переодически валится приложение из за System.AggregateException
.
Необработанное исключение типа "System.AggregateException" в System.Private.CoreLib.dll
One or more errors occurred.
System.AggregateException
HResult=0x80131500
Сообщение = One or more errors occurred. (Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.)
Источник = System.Private.CoreLib
Трассировка стека:
в System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException) в /_/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs:строка 724
в System.Threading.TimerQueueTimer.Fire(Boolean isThreadPool) в /_/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs:строка 669
в System.Threading.TimerQueue.FireNextTimers() в /_/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs:строка 331
в System.Threading.ThreadPoolWorkQueue.Dispatch() в /_/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs:строка 924
в System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart() в /_/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs:строка 77
Внутреннее исключение 1:
MySqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Внутреннее исключение 2:
TimeoutException: The operation has timed out.
В InnerExeptions[0].StackTrace:
в MySql.Data.Common.StreamCreator.<>c.<GetTcpStreamAsync>b__8_1()
в System.Threading.CancellationTokenSource.Invoke(Delegate d, Object state, CancellationTokenSource source) в /_/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs:строка 977
в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) в /_/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs:строка 179
--- Конец трассировки стека из предыдущего расположения ---
в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) в /_/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs:строка 203
в System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException) в /_/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs:строка 806
UPD
Свой вариант использования не могу предоставить.
Но не ловится исключение даже в такой простой конструкции:
while (true)
{
try
{
using MySqlConnection? _mySqlConnection = new MySqlConnection
{
ConnectionString = connectionStringBuilder.ToString()
};
await _mySqlConnection.OpenAsync();
}
catch (AggregateException ae)
{
foreach (Exception exception in ae.InnerExceptions)
{
Debug.WriteLine(exception);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
await Task.Delay(1000);
}
UPD
Перешёл на MySqlConnector - в коде изменений делать не пришлось, полёт нормальный.
Ответы (1 шт):
В данном случае забыли про catch не вы, а авторы библиотеки MySQL.Data. Судя по стеку, они при истечении тайм-аута пытаются отправить какую-то команду на сервер, чтобы отменить запрос, но у них это не получается, потому что у них истёк тайм-аут.
Классическая ошибка при обработке ошибки. И, так как это всё происходит при обработке тайм-аута - происходит оно в потоке пула, где вы никак исключение не перехватите.
Могу посоветовать добиться стабильного воспроизведения и отправить баг-репорт авторам, а самому тем временем перейти на нормальную СУБД с качественным драйвером. Например, на Postgres.
UPD: Вот строка с ошибкой: https://github.com/mysql/mysql-connector-net/blob/7456bd102cc4193d61b12f82312b3db063aacea1/MySQL.Data/src/common/StreamCreator.cs#L111
using (cancellationToken.Register(() => throw new MySqlException(Resources.Timeout, new TimeoutException())))
await tcpClient.ConnectAsync(settings.Server, (int)settings.Port).ConfigureAwait(false);
Они не просто упустили исключение из СancellationToken.Register, они его там зачем-то намеренно выкинули! Как будто выкидывание исключения из Register остановит асинхронную операцию.
Автор библиотеки вообще не понимает что делает, и ни разу не проверял свой код. Это не лечится, используйте другую СУБД. В крайнем случае - форкайте библиотеку и переписывайте.