gpt4 book ai didi

c# - Lambda 遇到 UnobservedTaskException - 无法访问已处置的对象

转载 作者:行者123 更新时间:2023-11-30 21:32:31 24 4
gpt4 key购买 nike

我一直在 AWS Lambda 的 CloudWatch 日志中注意到这个异常。

一切似乎都得到了处理,所以我认为这是在 Lambda 完成执行后创建的 AWS 代码(与我编写的代码相反)中的异常。

因为它在功能上有效,所以我一直忽略它,但我担心可能存在我没有注意到的问题。


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)"
]
}]
}

lambda 代码非常简单:它使用 Dapper 将这些 SNS 消息 添加到 SQL 数据库中。

我认为我在函数处理程序中执行 async 的方式可能存在一些问题。有什么想法吗?

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 block 中被捕获。如果是,则不会是 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;
}
}

最佳答案

日志消息简单明了并解释了正在发生的事情:

  • 你有一个异步任务
  • 该异步任务正在访问一个已被处置的对象,这可能是因为您的工作流中存在某种竞争条件,从而使异步工作流中的对象与需要它的工作流的另一部分乱序处置。 这意味着此工作流程中存在严重问题
  • 从不等待异步任务,无论是与 await 异步,还是(不要这样做!)与 Result 或 Wait 同步。这意味着永远不会采用异常的延续路径,并且任务在收集时会注意到这一点。 同样,如果您有一项从不等待结果的任务,那么您的工作流程中可能存在严重问题。将这一事实与前一点的事实结合起来:我们现在有两个证据相互加强,表明此工作流程中存在严重问题,并且它涉及一项在它完成时未等待的任务应该是为了确保排序约束。
  • 因此您在终结器线程上遇到异常,这非常糟糕

Since functionally it works I've been ignoring it

我曾经听说,当一家工厂着火并烧成平地时,人们通常会忽略或禁用七种不同的安全系统。摆脱这种认为它有效的习惯,所以它一定是安全的。也许这没什么,但在我有其他证据之前,我会认为这些消息表明存在严重问题。

关于c# - Lambda 遇到 UnobservedTaskException - 无法访问已处置的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52249998/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com