2017-04-18 4 views
-1

데이터를 IoT 허브로 계속 보내고 인터넷 연결이 끊어진 경우 SQL과 같은 로컬 데이터베이스에 저장해야합니다.Azure IoTHub에 데이터를 전송하는 동안 인터넷 연결이 끊긴 경우의 예외를 catch하는 방법

데이터를 IoT 허브에 보내려면 "deviceClient.SendEventAsync"라는 asyn 메서드가 있어야합니다. 여기서 device 클라이언트는 DeviceClient 클래스의 객체입니다.

이제는 asyn 메서드이므로 어떤 인터넷 연결도 없기 때문에 아무 예외도 발생시키지 않습니다. 따라서 이것을 잡아 로컬 SQL DB에 저장할 수 없습니다.

내부 방법은 내 코드

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 메서드를 호출하는 동안 예외를 캡처하는 다른 방법이있는 경우 알려 주시기 바랍니다.

이 작업을 위해 사용하고있는 전체 코드 구조를 찾으십시오. 인터넷 연결이 내려 때

  1. 이 코드는 예외를 한 번만 던지는 것 : 아래
    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. 다음 반복에서 "aresit taskresult;" 메서드를 중지 응답에서 및 이후 병동 반복에서 어떤 예외를 캡처 할 수 없습니다.

의견을 보내 주십시오.

+2

코드가있는 메소드와 호출 코드에 대한 서명을 제공 할 수 있습니까? –

+0

Async/Await 패턴의 일반적인 이해. ** task ** 대신 ** void **를 반환하는 Async 메서드에서 이러한 작업을 수행하고 있습니다. 따라서 실제 예외 대신 집계 예외가 발생합니다. 그리고 연결의 손실을 제대로 감지 할 수 없습니다. 신중하고 신중하게 [이 기사] (https://msdn.microsoft.com/en-us/library/mt674882.aspx)를 읽고 모든 비동기 메서드를 수정하십시오. 그런 다음 다시 질문하십시오! – astaykov

+0

@astaykov 비동기 무효화 메서드를 호출한다는 증거가 보이지 않습니다. 또한 async void는 try catch에 집계 예외를 발생시키지 않습니다. 비동기 void 예외는 발견되지 않습니다. 동기화 컨텍스트에 전달되고 try catch 이외의 다른 방법으로 처리되어야합니다. – bradgonesurfing

답변

0

I가 지속적으로 만약 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