c# - 在 Azure IoTEdge 的模块中启动长时间运行方法的最佳方式是什么?
问题描述
只要设备正在运行,我就需要保持活动功能。该方法位于模块内部。我遇到它在 3-10 小时后停止运行。
// Async method to send keepalive signals
private static async void SendKeepaliveToCloudMessagesAsync()
{
int keep_alive_counter = 0;
while (true)
{
try
{
String timestamp = DateTimeOffset.UtcNow.ToString("u");
String activity_type = "Device-Keepalive";
// Create JSON message
var telemetryDataPoint = new
{
timestamp,
activity_type,
device_id,
keep_alive_counter
};
var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
var message = new Message(Encoding.ASCII.GetBytes(messageString));
keep_alive_counter++;
// Add a custom application property to the message.
// An IoT hub can filter on these properties without access to the message body.
message.Properties.Add("keepaliveAlert", (keep_alive_counter < 30) ? "true" : "false");
// Send the telemetry message
await s_deviceClient.SendEventAsync(message);
Console.WriteLine("[{0}] > Sending Keepalive message: {1}", DateTimeOffset.UtcNow.ToString("u"), messageString);
await Task.Delay(s_keepaliveInterval * 1000);
}
catch (Exception ex)
{
Console.Error.WriteLine("Send keepalive Failed! {0}", ex);
}
}
}
上面的代码工作正常,3-10 小时,但突然停止,我没有收到 IoTHub 上的保持活动消息。
我设法从日志中得到以下消息:
Send keepalive Failed! System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'IoT Client'.
at Microsoft.Azure.Devices.Client.Transport.DefaultDelegatingHandler.ThrowIfDisposed()
at Microsoft.Azure.Devices.Client.Transport.DefaultDelegatingHandler.OpenAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.<>c__DisplayClass32_0.<<OpenAsyncInternal>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.EnsureOpenedAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.<>c__DisplayClass14_0.<<SendEventAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.SendEventAsync(Message message, CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.InternalClient.SendEventAsync(Message message)
at MotionDetection.Program.SendKeepaliveToCloudMessagesAsync() in /app/Program.cs:line 439
解决方案
虽然您看到的错误不应该发生,但我仍然可以回答实际问题:
您构建模块以无限时间发送消息的方式看起来不错,并且通常应该可以工作。实际上,官方 repo 中的 IoT Edge 团队的样本之一与您的非常相似,请参见此处(对于 case when SendUnlimitedMessages()
is true
)。
Maybe just follow their example and implement a shutdown handler as well for a clean exit strategy.
推荐阅读
- java - 如何 JUnit 测试 try catch 块
- jenkins - 在声明性 Jenkins 管道中使用并行节点注册 Junit 测试结果
- django - 在 Django 中查看日期是否在 7 天内
- javascript - 将 jest 配置为现有的 react native 应用程序
- java - android studio中java中的计算器括号
- javascript - 阅读更多阅读更少功能
- flutter - 位置参数太多:预期为 0,但找到了 1。尝试删除额外的参数
- karate - 如何在 responseCode == 和 != 上为一个 API 添加 if 条件
- javascript - 带自动滑动的滑块部分
- tensorflow - Seaborn 无法为特定特征绘制热图(泰坦尼克数据集)