How can I tell when an update on an Azure IoT Hub device twin is finished?

843 Views Asked by At

I'm developing a web application that makes changes to device twins in an Azure IoT Hub. So the user of the web application can make changes to a device twin through my web and then he can query the device properties again if he wants - but if he's quick enough, his changes will not have been made to the device twin yet.

I'm using Microsoft.Azure.Devices.RegistryManager.UpdateTwinAsync() to change device twins. The problem is that this is an async method that doesn't have a callback parameter to let me know when the update has finished. Therefore I cannot know when the change on the device twin has been made - and might get the older version if I query it too quickly after updates. How can I detect when updates are 100% done?

...surely, everyone who has used UpdateTwinAsync() has run into this problem, right?

EDITED:

Ok, I've done some testing on this and I'm pretty sure that when the call to

await registryManager.UpdateTwinAsync(deviceId, patch, etag);

finishes, i.e. the program goes to the next line after this one, the device twin has NOT been updated yet. Rather, some update sequence has been started in the IoT Hub. Therefore, the next line after this one cannot be sure that the device twin is updated.

To me this sounds like a bad design. Why make UpdateTwinAsync() an async method that I can "await" on?

Perhaps there is a way around it by immedially fetch the device twin IN my UpdateDevice() method and check if the twin "version" has been increased and only then return a status code from my method. FYI, my method is called UpdateDevice() and the browser calls it on the web server backend, which in turn calls UpdateTwinAsync() on the IoT Hub.

1

There are 1 best solutions below

3
On

Have you tried to use the await operator? Here is the code.

var twin = await registryManager.GetTwinAsync("myDeviceId");
var patch =
    @"{
        tags: {
            location: {
                region: 'US',
                plant: 'Redmond43'
            }
        }
    }";
await registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);

var query = registryManager.CreateQuery(
  "SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'", 100);
var twinsInRedmond43 = await query.GetNextAsTwinAsync();
Console.WriteLine("Devices in Redmond43: {0}", 
  string.Join(", ", twinsInRedmond43.Select(t => t.DeviceId)));

For more information https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-csharp-csharp-twin-getstarted