title: Lambda encountered an UnobservedTaskException - Cannot access a disposed object
body: <p>I've been noticing this exception in the CloudWatch logs for an AWS Lambda. </p>
  
  <p>Everything seems to get processed so I think it is an exception within the AWS code (as opposed to something I've written) that is created after the Lambda has finished executing. </p>
  
  <p>Since functionally it works I've been ignoring it but I'm concerned that there might be problems that I haven't noticed. </p>
  
  <hr>
  
  <p><strong>Lambda encountered an UnobservedTaskException via 
  'TaskScheduler.UnobservedTaskException' event:</strong></p>
  
  <pre><code>{
      "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&amp; remoteEP)",
              "at System.Net.Sockets.UdpClient.&lt;&gt;c.&lt;ReceiveAsync&gt;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&amp; remoteEP)",
              "at System.Net.Sockets.UdpClient.&lt;&gt;c.&lt;ReceiveAsync&gt;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)"
          ]
      }]
  }
  </code></pre>
  
  <p>The lambda code is pretty simple: It adds these <code>SNS messages</code> into an SQL database using <code>Dapper</code>. </p>
  
  <p>I'm thinking that there might be some problem with how I'm doing <code>async</code> in the Fucntion handler. Any ideas?</p>
  
  <pre><code>public class Function
  {
      private static string _connectionString;
  
      public async Task&lt;IEnumerable&lt;InsertSnsResult&gt;&gt; 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");
          }
      }
  }
  </code></pre>
  
  <p>[Edit]</p>
  
  <p>Just be clear here, this exception does not get caught in the try/catch block. If it did it wouldn't be an <code>UnobservedTaskException</code>. That's why I'm having trouble getting to the root of the problem. </p>
  
  <p>And this is the repository code</p>
  
  <pre><code>public async Task&lt;List&lt;InsertSnsResult&gt;&gt; InsertSnsMessages(IEnumerable&lt;SnsEvent&gt; records)
  {
      using (var connection = new SqlConnection(_connectionString))
      {
          await connection.OpenAsync().ConfigureAwait(false);
  
          var results = new List&lt;InsertSnsResult&gt;();
          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;
      }            
  }
  </code></pre>