2017-04-18 4 views
-1

私はIoTハブにデータを継続的に送信する必要があり、インターネット接続がダウンするとSQLなどのローカルデータベースに格納する必要があります。Azure IoTHubにデータを送信中に例外が発生した場合の対処方法

データをIoTハブに送信するには、「deviceClient.SendEventAsync」というasynメソッドがあります ここで、デバイスクライアントはDeviceClientクラスのオブジェクトです。

これはasynメソッドなので、インターネットに接続していないときは例外をスローしていないので、これを捕まえてローカルのSQLデータベースに保存することはできません。

メソッド内で私のコードは

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. 
    } 

のようなものです。しかし、私は、任意の障害または全くインターネット接続の場合には例外を取得したことがないですし、コードの実行は続けるです。

この問題に取り組んでください。

また、asynメソッドを呼び出す際に例外をキャプチャする方法が他にもある場合は、お知らせください。

この操作に使用しているコードの構造全体を確認してください。以下は

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); 
      } 
     } 

    } 
} 

である私の2つの観察です:

  1. このコードは、インターネット 接続が降りて一度だけ例外をスローします。
  2. 次の反復から、 "await taskresult;"メソッドを停止して と応答しているので、私は の例外をキャプチャすることができません。

ご意見をお寄せください。

+2

コードが存在するメソッドと呼び出しコードのシグネチャを指定できますか? –

+0

Async/Awaitパターンの一般的な誤解。 ** task **ではなく** void **を返すAsyncメソッドでこれらのアクションを実行しています。そのため、実際の例外の代わりに集計例外が発生します。そして、接続の喪失を適切に検出できません。注意深く[この記事](https://msdn.microsoft.com/en-us/library/mt674882.aspx)をよく読んで、すべての非同期メソッドを修正してください。その後、もう一度質問してください! – astaykov

+0

@astaykov私は彼が非同期voidメソッドを呼び出している証拠は表示されません。また、async voidはtry catchに集計例外を発生させません。非同期void例外は捕捉できません。それらは同期コンテキストに配信され、try catch以外の方法で処理されなければなりません。 – bradgonesurfing

答えて

0

私は連続したIoTハブにメッセージを送信し、ループ内の次のコードを持っている:私は、このランニングを設定した場合

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); 
} 

をした後、コンピュータをネットワークから切り離し、私は出力でこれを参照してください。

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. 

これは、あなたがSendEventAsync方法からAggregateExceptionsをキャッチすることができていることを示しています。どのプラットフォームでコードを実行していますか?

+0

こんにちはドミニクネットワークからコンピュータを切断し、このコードを初めて実行し、この例外をキャプチャできるかどうかを教えてください。また、これらのコードをwhileループに入れて、失敗した反復の後に反復例外を捕捉できるかどうかをチェックしてください。 – JARVIS

関連する問題