public async Task RunAsync() { ConsoleLogger.LogInfo($"IotHubHost={EnvironmentVariables.IotHubHost}, GatewayHost={EnvironmentVariables.EdgeHubHost}, ParentEdgeDeviceId={EnvironmentVariables.EdgeDeviceId}, LeafDevicePrefix={EnvironmentVariables.LeafDeviceIdPrefix}."); var cancellationTokenSource = new CancellationTokenSource(TestPeriod); var device = await DeviceManager.RetrieveDeviceAsync(); var deviceId = device.Id; d2cMessagesTopic = string.Format(CultureInfo.InvariantCulture, TelemetryTopicPattern, deviceId); c2dMessagesTopic = string.Format(CultureInfo.InvariantCulture, C2DMessagesTopicPattern, deviceId); var host = EnvironmentVariables.EdgeHubHost == null ? EnvironmentVariables.IotHubHost : EnvironmentVariables.EdgeHubHost; mqttClient = new MQTTnetClient(host, 8883, true); mqttClient.RegisterConnectionStatusListener(this); mqttClient.RegisterMessageHandler(this); while (!mqttClient.IsConnected()) { try { var username = $"{host}/{WebUtility.UrlEncode(deviceId)}/?api-version=2018-06-30"; var password = DeviceManager.CreateDeviceSasToken(host, deviceId, device.Authentication.SymmetricKey.PrimaryKey, Convert.ToInt32(TokenTTL.TotalSeconds)); await mqttClient.ConnectAsync(deviceId, username, password, new CancellationTokenSource(OperationTimeOut).Token); } catch (Exception ex) { ConsoleLogger.LogInfo($"Connect device {deviceId} to {host} with native MQTT client failed, retry after 1 second: {ex}"); await Task.Delay(TimeSpan.FromSeconds(1)); } } var subscriptions = new Dictionary <string, Qos>() { [$"{c2dMessagesTopic}/#"] = Qos.AtLeastOnce, [$"{TwinUpdateTopic}/#"] = Qos.AtMostOnce, [$"{MethodRequestTopic}/#"] = Qos.AtMostOnce }; if (EnvironmentVariables.CustomSubscriptionTopics != null) { var customTopics = EnvironmentVariables.CustomSubscriptionTopics.Split(";"); foreach (var topic in customTopics) { subscriptions[topic] = Qos.AtLeastOnce; } } await mqttClient.SubscribeAsync(subscriptions, new CancellationTokenSource(OperationTimeOut).Token); await Task.WhenAll(D2CLoop(deviceId, cancellationTokenSource.Token), C2DLoop(deviceId, cancellationTokenSource.Token)); await mqttClient.DisconnectAsync(new CancellationTokenSource(OperationTimeOut).Token); }