Лямбда обнаружила UnobservedTaskException - Невозможно получить доступ к удаленному объекту - PullRequest
0 голосов
/ 10 сентября 2018

Я заметил это исключение в журналах CloudWatch для AWS Lambda.

Кажется, что все обрабатывается, поэтому я думаю, что это исключение в коде AWS (в отличие от того, что я написал), которое создается после того, как Lambda закончила работу.

Так как функционально это работает, я игнорирую это, но я обеспокоен тем, что могут быть проблемы, которые я не заметил.


Lambda обнаружила исключение UnobservedTaskException через Событие 'TaskScheduler.UnobservedTaskException':

{
    "errorType": "AggregateException",
    "errorMessage": "A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. (Cannot access a disposed object.\nObject name: 'System.Net.Sockets.UdpClient'.)",
    "cause": {
        "errorType": "ObjectDisposedException",
        "errorMessage": "Cannot access a disposed object.\nObject name: 'System.Net.Sockets.UdpClient'.",
        "stackTrace": [
            "at System.Net.Sockets.UdpClient.EndReceive(IAsyncResult asyncResult, IPEndPoint& remoteEP)",
            "at System.Net.Sockets.UdpClient.<>c.<ReceiveAsync>b__56_1(IAsyncResult asyncResult)",
            "at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)"
        ]
    },
    "causes": [ {
        "errorType": "ObjectDisposedException",
        "errorMessage": "Cannot access a disposed object.\nObject name: 'System.Net.Sockets.UdpClient'.",
        "stackTrace": [
            "at System.Net.Sockets.UdpClient.EndReceive(IAsyncResult asyncResult, IPEndPoint& remoteEP)",
            "at System.Net.Sockets.UdpClient.<>c.<ReceiveAsync>b__56_1(IAsyncResult asyncResult)",
            "at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)"
        ]
    }]
}

Лямбда-код довольно прост: он добавляет эти SNS messages в базу данных SQL, используя Dapper.

Я думаю, что может быть какая-то проблема с тем, как я делаю async в обработчике Fucntion. Есть идеи?

public class Function
{
    private static string _connectionString;

    public async Task<IEnumerable<InsertSnsResult>> FunctionHandler(SNSEvent @event, ILambdaContext context)
    {
        try
        {
            context.Logger.LogLine("Adding SNS Messages");
            _connectionString = _connectionString ?? await DecryptHelper.DecryptEnvironmentVariableAsync("ConnectionString").ConfigureAwait(false);
            var handler = new AddSnsMessageHandler(new SnsMessagesRepository(_connectionString, context.Logger));
            return await handler.AddSnsEvents(@event).ConfigureAwait(false);
        }
        catch (Exception e)
        {
            context.Logger.LogLine(e.Message);
            throw;
        }
        finally
        {
            context.Logger.LogLine("Finished SNS Adding Messages");
        }
    }
}

[редактировать]

Просто будьте ясны, это исключение не попадает в блок try / catch. Если бы это было так, это не было бы UnobservedTaskException. Вот почему у меня проблемы с получением корня проблемы.

А это код репозитория

public async Task<List<InsertSnsResult>> InsertSnsMessages(IEnumerable<SnsEvent> records)
{
    using (var connection = new SqlConnection(_connectionString))
    {
        await connection.OpenAsync().ConfigureAwait(false);

        var results = new List<InsertSnsResult>();
        foreach (var record in records)
        {
            try
            {
                await connection.ExecuteAsync(InsertEventCommand, record).ConfigureAwait(false);
                results.Add(new InsertSnsResult(record.CorrelationId, true));
            }
            catch (Exception ex)
            {
                _logger.LogLine($"InsertSns failed for {record.Id}. {ex.Message}");
                results.Add(new InsertSnsResult(record.CorrelationId, false));
            }
        }

        return results;
    }            
}

1 Ответ

0 голосов
/ 10 сентября 2018

Сообщения журнала просты и объясняют, что происходит:

  • У вас есть асинхронная задача
  • Эта асинхронная задача обращается к объекту, который уже был удален, возможно, из-за того, что в вашем рабочем процессе есть какое-то состояние гонки, в результате которого объект в асинхронном рабочем процессе выходит из строя с другой частью рабочего процесса, которая в этом нуждается. Это означает, что что-то серьезно нарушено в этом рабочем процессе .
  • Асинхронная задача никогда не ожидается, либо асинхронно с await, либо (не делайте этого!) Синхронно с Result или Wait. Это означает, что исключительный путь продолжения никогда не берется, и задача замечает это, когда он собирается. Опять же, возможно, что-то серьезно нарушено в вашем рабочем процессе, если у вас есть задача, которую вы никогда не дождетесь результата . Объедините этот факт с фактом из предыдущего пункта: теперь у нас есть два доказательства, которые подтверждают друг друга, что что-то серьезно нарушено в этом рабочем процессе и что оно включает в себя задачу, которая не ожидается, когда она должна быть для обеспечения ограничения заказа.
  • И, следовательно, вы получите исключение для вашего потока финализатора, которое очень плохо .

Так как функционально это работает, я игнорирую это

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...