Необработанное исключение типа "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 шт):

Автор решения: Pavel Mayorov

В данном случае забыли про 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 остановит асинхронную операцию.

Автор библиотеки вообще не понимает что делает, и ни разу не проверял свой код. Это не лечится, используйте другую СУБД. В крайнем случае - форкайте библиотеку и переписывайте.

→ Ссылка