C#向Azure IoT Hub插入CSV数据时提示框提前触发问题求解
问题根因
你当前的代码存在4个核心问题,直接导致未等待全量数据上传完成就提前返回:
- 大量异步调用未加
await关键字,包括s_deviceClient.OpenAsync()、s_deviceClient.CloseAsync(),这些操作未完成就会直接走后续逻辑,方法提前结束。 - 设备不存在的else分支中,仅调用了
s_deviceClient.SendEventAsync(message)但未等待该任务执行完成,反而直接等待10秒延时,大概率消息还没上传成功,延时结束方法就直接返回了。 - 首次调用方法时
registryManager为null,你仅做了初始化操作,未执行任何消息发送逻辑,该次调用直接无操作返回。 - 上层批量调用该方法时,未等待所有上传任务全部完成就触发了成功提示。
修复后的代码
// 建议把DeviceClient改成复用模式,不要每条消息都创建销毁连接,这里先基于你的原有逻辑修复 private async Task DataSendstoAzureIotHub(string jsonserv, string deviceID) { DeviceClient s_deviceClient; Console.WriteLine("upload time start" + DateTime.Now); try { // 初始化registryManager后也要执行发送逻辑,不要跳过 if (registryManager == null) { registryManager = RegistryManager.CreateFromConnectionString(s_connectionString01); } // 不管registryManager是不是刚初始化,都要走发送逻辑,不要放else里 Device device = await registryManager.GetDeviceAsync(deviceID); string s_connectionStringNew = "*"; // 这里替换成你自己的连接字符串生成逻辑 if (device == null) { device = await registryManager.AddDeviceAsync(new Device(deviceID)); } s_deviceClient = DeviceClient.CreateFromConnectionString(s_connectionStringNew, Microsoft.Azure.Devices.Client.TransportType.Amqp); await s_deviceClient.OpenAsync(); // 加await等待连接打开 var message = new Message(Encoding.UTF8.GetBytes(jsonserv)); message.Properties.Add("southnorth_msgid", "com.intel.wsn.sensorData"); await s_deviceClient.SendEventAsync(message); // 直接await发送任务,不要用多余的task变量 await s_deviceClient.CloseAsync(); // 加await等待连接关闭 await Task.Delay(10); Console.WriteLine("Single record upload finished: " + DateTime.Now); } catch (Exception ex) { Log.Error(ex); // 建议在这里抛出异常,上层可以感知到发送失败,不要吞异常 throw; } }
批量调用参考逻辑
上层循环处理CSV所有记录时,用Task.WhenAll等待所有上传任务完成再弹提示:
List<Task> uploadTasks = new List<Task>(); // 遍历所有CSV记录生成json和deviceId后 foreach (var record in csvRecords) { string json = ConvertToJson(record); string deviceId = record.DeviceId; uploadTasks.Add(DataSendstoAzureIotHub(json, deviceId)); } // 等待所有上传任务全部完成 await Task.WhenAll(uploadTasks); // 这里再弹出数据插入成功提示 MessageBox.Show("数据插入成功");
性能优化建议
- 不要每条消息都创建、销毁DeviceClient连接,相同设备的消息复用同一个DeviceClient长连接,吞吐量可以提升10倍以上
- 可以采用批量发送接口
SendEventBatchAsync,一次上传多条消息,减少IO开销 - 提前批量查询所有需要用到的设备是否存在,不要每条消息都调用一次
GetDeviceAsync,降低IoT Hub接口调用频率,避免被限流
内容的提问来源于stack exchange,提问作者Malathi
相关产品推荐
相关产品推荐

