2017-04-18 2 views
-1

J'ai besoin d'envoyer des données en permanence au concentrateur IoT et si la connectivité Internet est coupée, je dois la stocker dans une base de données locale comme SQL.Comment attraper une exception en l'absence de connexion Internet lors de l'envoi de données à Azure IoTHub

Pour envoyer des données au concentrateur IoT, nous avons une méthode asyn qui est "deviceClient.SendEventAsync" où le client de périphérique est l'objet de la classe DeviceClient.

Maintenant, puisque c'est la méthode asyn il ne jette pas d'exception quand aucune connexion Internet est là, donc je ne suis pas capable d'attraper cela et stocker dans sql local db.

méthode Dans mon code est comme

try 
    { 
    await deviceClient.SendEventAsync(message) ; 
    } 
    catch(AggregateException) 
    { 
     //If exception found then store same msg to local database. 
    }  
    catch(Exception ex) 
    { 
    //If exception found then store same msg to local database. 
    } 

Mais je ne devient une exception en cas de faute ou pas de connectivité Internet et l'exécution de code est continuer.

S'il vous plaît aidez-moi à résoudre ce problème. Egalement, faites-moi savoir s'il existe d'autres moyens de capturer l'exception lors de l'appel d'une méthode asyn.

Veuillez trouver la structure de code entière que j'utilise pour cette opération.

namespace D2CDeviceDataSender 
{ 
    class Program 
    { 
     private static DeviceClient deviceClient; 
     private static string iotHubUri = string.Empty; 
     private static string deviceKey = string.Empty; 
     private static string deviceName = string.Empty; 

     static void Main(string[] args) 
     { 
      try 
      { 
       iotHubUri = ConfigurationManager.AppSettings["IoTHubURI"].ToString(); 
       deviceName = ConfigurationManager.AppSettings["DeviceName"].ToString(); 
       deviceKey = ConfigurationManager.AppSettings["DeviceKey"].ToString(); 
       deviceClient = DeviceClient.Create(iotHubUri, new DeviceAuthenticationWithRegistrySymmetricKey(deviceName, deviceKey), Microsoft.Azure.Devices.Client.TransportType.Mqtt); 

       Task.Factory.StartNew(() => SendDeviceToCloudMessagesAsync1()); 
       Console.ReadLine(); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
       Console.WriteLine("Press any key to exit....."); 
       Console.ReadLine(); 
      } 
     } 

     public static async Task SendDeviceToCloudMessagesAsync1() 
     { 
      while (true) 
      { 
       try 
       { 
        double avgWindSpeed = 10; // m/s 
        Random rand = new Random(); 
        double currentWindSpeed = avgWindSpeed + rand.Next(); 
        var telemetryDataPoint = new 
        { 
         DeviceCode = "myFirstDevice", 
         Date = DateTime.UtcNow, 
        }; 

        string messageString = JsonConvert.SerializeObject(telemetryDataPoint); 
        var message = new Message(Encoding.ASCII.GetBytes(messageString)); 
        Task taskresult = deviceClient.SendEventAsync(message); 
        await taskresult; 
        Console.WriteLine("Data sent to IoT hub :" + DateTime.Now + " " + messageString); 
       } 
       catch (IotHubCommunicationException ex) 
       { 
        Console.WriteLine(ex.Message); 
        Console.WriteLine(ex.InnerException); 
        Console.WriteLine("Internet connectivity down insert data to local database !"); 
       } 
       catch (AggregateException ex) 
       { 
        Console.WriteLine(ex.Message); 
        Console.WriteLine(ex.InnerException); 
        Console.WriteLine("Internet connectivity down insert data to local database !"); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine(ex.Message); 
        Console.WriteLine(ex.InnerException); 
        Console.WriteLine("Internet connectivity down insert data to local database !"); 
       } 

       Thread.Sleep(5000); 
      } 
     } 

    } 
} 

Voici mes deux observation qui est:

  1. Ce code lancer exception qu'une seule fois lorsque la connexion Internet descendre.
  2. A partir de l'itération suivante, "wait taskresult;" méthode dans l'arrêt répondant et de l'itération sur le pupitre de sorte que je ne suis pas en mesure de capturer aucune exception.

Veuillez nous retourner vos commentaires.

+2

Pouvez-vous fournir la signature pour la méthode où ce code est et le code appelant? –

+0

malentendu commun du motif Async/Await. Vous effectuez ces actions dans une méthode Async qui renvoie ** void ** au lieu de ** task ** - C'est pourquoi vous vous retrouvez avec une exception d'agrégat au lieu des exceptions réelles. Et vous ne pouvez pas détecter correctement la perte de connectivité. Veuillez lire attentivement et avec attention [cet article] (https://msdn.microsoft.com/fr-fr/library/mt674882.aspx) et corrigez toutes vos méthodes asynchrones. Ensuite, posez votre question à nouveau! – astaykov

+0

@astaykov Je ne vois aucune preuve qu'il appelle des méthodes async void. De plus, async void n'entraîne pas d'exceptions globales dans le catch try. Les exceptions async void ne peuvent pas être interceptées. Ils sont livrés dans le contexte de la synchronisation et doivent être manipulés d'une autre manière que d'essayer d'attraper. – bradgonesurfing

Répondre

0

je le code suivant dans une boucle qui envoie en continu des messages à IdO Hub:

try 
{ 
    await deviceClient.SendEventAsync(message); 
    Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString); 
} 
catch (AggregateException e) 
{ 
    Console.WriteLine("{0} > Error Sending message: {1}", DateTime.Now, messageString); 
    Console.WriteLine("AggregateException: {0} ", e.Message); 
} 

Si je mets cette course, puis débranchez l'ordinateur du réseau, je vois cela dans la sortie:

19/04/2017 09:11:47 > Sending message: {"deviceId":"myFirstDevice","windSpeed":10.042793008518775} 
19/04/2017 09:11:52 > Sending message: {"deviceId":"myFirstDevice","windSpeed":8.5088816902175921} 
19/04/2017 09:11:58 > Sending message: {"deviceId":"myFirstDevice","windSpeed":10.399840490147398} 
19/04/2017 09:12:22 > Error Sending message: {"deviceId":"myFirstDevice","windSpeed":10.388208727533094} 
AggregateException: One or more errors occurred. 

Cela montre que vous pouvez attraper AggregateExceptions de la méthode SendEventAsync. Sur quelle plateforme utilisez-vous votre code?

+0

Salut Dominic s'il vous plaît déconnectez l'ordinateur du réseau et exécutez ce code la première fois puis laissez-moi savoir si vous êtes en mesure de capturer cette exception ou non. Mettez également ce code dans la boucle while et vérifiez que, après une itération échouée, vous êtes en mesure de capturer l'exception d'itération suivante ou pas. En recherchant Ward pour votre réponse. – JARVIS