2

作为 IoTHub DeviceClient 初始化的一部分,我明确打开与 OpenAsync 的连接,然后立即调用 SetDesiredPropertyUpdateCallbackAsync。有时当我调用 SetDesiredPropertyUpdateCallbackAsync 时,它会超时并出现异常。如果我的网络连接稳定,为什么我没有在 OpenAsync 而不是 SetDesiredPropertyUpdateCallbackAsync 上获得超时?我相信它甚至会在内部进行相同的 OpenAsync 调用以确保连接是打开的。

ioTHubModuleClient = DeviceClient.CreateFromConnectionString(ConnectionString, settings);
await ioTHubModuleClient.OpenAsync().ConfigureAwait(false);
await ioTHubModuleClient.SetDesiredPropertyUpdateCallbackAsync(OnModulePropertyUpdateRequested, this).ConfigureAwait(false);

更新: 我发现如果我在此之前注册 SetConnectionStatusChangesHandler,我可以看到它无休止地连接/断开连接,直到我调用 SetDesiredPropertyUpdateCallbackAsync 时超时。

IoTHub 连接现在已连接原因:Connection_Ok IoTHub 连接现在已断开_重试原因:No_Network IoTHub 连接现在已连接原因:Connection_Ok IoTHub 连接现在已断开_重试原因:No_Network IoTHub 连接现在已连接原因:Connection_Ok IoTHub 连接现在已断开_重试原因:No_Network

我使用 dotPeek 反编译 Microsoft.Azure.Devices 内容并通过本地 pdb 服务器提供服务。似乎正在发生的事情是某些东西正在为成功的操作生成 SocketException。异常消息是“操作成功完成”。此博客指出这通常是由于 dllimport 调用未使用SetLastError所致。我在调用堆栈中看不到任何明显导致 pinvoke 调用的内容:

在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttIotHubAdapter.d__40.MoveNext() --- 结束从以前抛出异常的位置的堆栈跟踪 --- 在 Microsoft.Azure.Devices.Client.Transport 的 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 的 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()。 Mqtt.MqttIotHubAdapter.d__28.MoveNext()

4

1 回答 1

-2

一般来说,在 Console App 或 Service 场景中工作时,没有安装 SynchronizationContext(默认情况下),因此 ConfigureAwait 中的 continueOnCapturedContext 选项将不起作用。但是如果您碰巧安装或使用安装了SynchronizationContext的库,则该行为异步方法的一部分将与 UI 应用程序中的一样。ConfigureAwait(false)会改变上下文。一个重要的规则是每个异步方法都有自己的上下文,这意味着调用方法不受ConfigureAwait的影响。您可以参考这些主题以了解有关Task.ConfigureAwait的详细信息。

于 2018-01-23T03:05:52.397 回答