c# - Lambda 遇到 UnobservedTaskException - 无法访问已处置的对象
问题描述
我一直在 AWS Lambda 的 CloudWatch 日志中注意到此异常。
一切似乎都得到了处理,所以我认为这是在 Lambda 完成执行后创建的 AWS 代码中的一个异常(与我编写的代码相反)。
由于它在功能上有效,我一直忽略它,但我担心可能存在我没有注意到的问题。
Lambda 通过 'TaskScheduler.UnobservedTaskException' 事件遇到了 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 代码非常简单:它SNS messages
使用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;
}
}
解决方案
日志消息很简单,并解释了正在发生的事情:
- 你有一个异步任务
- 该异步任务正在访问一个已经被释放的对象,可能是因为您的工作流中有一些竞争条件,异步工作流中的一个对象与需要它的工作流的另一部分无序释放。 这意味着这个工作流程中的某些东西被严重破坏了。
- 异步任务从不等待,要么与 await 异步,要么(不要这样做!)与 Result 或 Wait 同步。这意味着永远不会采用异常延续路径,并且任务在收集它时会注意到这一点。同样,如果您有一项从不等待结果的任务,那么您的工作流程中可能会出现严重问题。将这一事实与前一点的事实相结合:我们现在有两个证据相互支持,表明此工作流程中存在严重问题,并且它涉及一个未等待的任务,而该任务本应确保排序约束.
- 因此,您在终结器线程上遇到异常,这真的很糟糕。
由于它在功能上有效,我一直忽略它
我曾经听说,当一家工厂着火并被烧毁时,平均有七种不同的安全系统被人们忽视或禁用。摆脱这种认为它有效的习惯,所以它必须是安全的。也许没什么,但我会认为这些消息表明存在严重问题,直到我有其他证据。
推荐阅读
- reactjs - 可编辑的 React-MaterialUI TextField 组件
- amazon-web-services - AWS - SQS 批量大小和 Lambda 方法
- javascript - 如何从玩笑测试中显示 Junit XML 中的错误?
- python - 在 Json 中通过 python 访问 kdb+/q 表?
- python - 将 TensorFlow 模型转换为 tensorflow-lite (.tflite) 格式时出现问题
- bash - 设置 cron-tab 以在 /var/log 中写入日志
- javascript - 更新可变刀片模板
- delphi - 带十进制值的 TProgressBar
- php - 如何从 Wordpress 管理员替换帖子和页面的所有外部/预览
- c# - 如何将 dd/mm/yyyy 转换为 M/d/yyyy