2

As part of my initialization of an IoTHub DeviceClient I explicitly open the connection with OpenAsync and then immediately call SetDesiredPropertyUpdateCallbackAsync. Sometimes when I call SetDesiredPropertyUpdateCallbackAsync it times out with an exception. If my network connection is stable, why don't I get the timeout on OpenAsync instead of SetDesiredPropertyUpdateCallbackAsync? I believe it even makes the same OpenAsync call internally to ensure the connection is open.

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

Update: I found that if I register with SetConnectionStatusChangesHandler before that, I can see that its endlessly connecting/disconnecting until it times out when I call SetDesiredPropertyUpdateCallbackAsync.

IoTHub connection is now Connected Reason: Connection_Ok IoTHub connection is now Disconnected_Retrying Reason: No_Network IoTHub connection is now Connected Reason: Connection_Ok IoTHub connection is now Disconnected_Retrying Reason: No_Network IoTHub connection is now Connected Reason: Connection_Ok IoTHub connection is now Disconnected_Retrying Reason: No_Network

I used dotPeek to decompile the Microsoft.Azure.Devices stuff and serve it up through a local pdb server. What seems to be happening is that something is generating a SocketException for a successful operation. The exception messages is "The operation completed successfully". This blog indicates this is typically due to a dllimport call not using SetLastError. I don't see anything in the callstack that obviously leads to a pinvoke call though:

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttIotHubAdapter.d__40.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttIotHubAdapter.d__28.MoveNext()

Tim
  • 412
  • 7
  • 18

1 Answers1

-2

Generally, when working in a Console App or Service scenario, there is no SynchronizationContext installed (by default), so the continueOnCapturedContext option in ConfigureAwait will have no effect.However if you happen to install or use a library that installs a SynchronizationContext, the behavior of the async methods will be like in UI application. ConfigureAwait(false) will change the context.An important rule is that each async method has its own context,it means that the calling method is not affected by ConfigureAwait. You can refer to these topics to get good know details about Task.ConfigureAwait.

Michael Xu
  • 4,382
  • 1
  • 8
  • 16