2016-09-28 40 views
0

我有下面的代碼,它從覆盆子pi上的傳感器讀取溫度。瞬態錯誤發生,deviceclient.sendmessage

代碼是異步的,如果我只刪除代碼的最後一行,發送消息的那一行,我永遠不會得到異常。 我的意思是這條線:

await deviceClient.SendEventAsync(message); 




private async void InitializeSensors() 
     { 
      string calibrationData; 
      //_periodicTimer.Dispose(); 
      // Inicializar el sensor bmp180 
      try 
      { 
       _bmp180 = new Bmp180Sensor(); 
       await _bmp180.InitializeAsync(); 
       calibrationData = _bmp180.CalibrationData.ToString(); //Retorna una cadena que representa al objeto actual. 
       if (_periodicTimer == null) 
       { 
        _periodicTimer = new Timer(this.TimerCallback, null, 0, readingInterval); 
       } 
      } 
      catch (Exception ex) 
      { 
       calibrationData = "Error de dispositivo! " + ex.Message; 
      } 

      var task = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
      { 
       //calibrationDataTextBlock.Text = ""; 
      }); 
     } 

     public async void TimerCallback(object state) 
     { 
      string temperatureText; 
      // Leer datos del sensor 
      try 
      { 
       var sensorData = await _bmp180.GetSensorDataAsync(Bmp180AccuracyMode.UltraHighResolution); 
       temperatureText = sensorData.Temperature.ToString(""); 
       //pressureText = sensorData.Pressure.ToString("F2"); 
       temperatureText += "°C"; 
       //pressureText += "hPa - " + BitConverter.ToString(sensorData.UncompestatedPressure); 
       var temperatureDataPoint = new 
       { 
        deviceKey = deviceKey, 
        deviceName = deviceName, 
        temperatura = sensorData.Temperature, 
        fecha = DateTime.Now 
       }; 
       var messageString = JsonConvert.SerializeObject(temperatureDataPoint); 
       var message = new Microsoft.Azure.Devices.Client.Message(Encoding.ASCII.GetBytes(messageString)); 
       message.Properties["Ambiente"] = ambiente; 

       ////temperatura.Text = temperatureText; 
       await deviceClient.SendEventAsync(message); 
      } 
      catch (Exception ex) 
      { 
       temperatureText = "Sensor Error: " + ex.Message; 
       //pressureText = "Sensor Error: " + ex.Message; 
      } 

      //// actualizaciones de la interfaz de usuario... deben ser invocados en el subproceso de interfaz de usuario 
      var task = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
      { 
       temperatura.Text = temperatureText; 
      }); 

     } 

如果我刪除行,我可以看到,傳感器工作,因爲文本框與實際temmperature更新。

只有當我去掉了SendMessage函數線我得到的異常

我怎樣才能解決這個問題?

+0

你得到了什麼異常? – Jackie

+0

通用Windows應用程序未處理的類型爲'System.ExecutionEngineException'的異常 – gina

回答

1

好吧,看起來像你有一些線程安全問題。

根據https://msdn.microsoft.com/en-us/library/microsoft.azure.devices.client.deviceclient.aspx,(DeviceClient的)任何實例成員不保證是線程安全的。

因此,當您使用像SendEventAsync這樣的東西時,您(開發人員)有責任關心線程安全性。

在你的情況,當你揭開序幕計時器,該框架將創建工作線程每個蜱經過的時間,這可能是一個問題,尤其是當

await deviceClient.SendEventAsync(message); 

的延遲undeterministic,所以你可能結束幾個工作線程進行相同的SendEventAsync調用。

一個快速和簡單的解決方法是添加的AutoResetEvent解決此API調用(更衣室不AWAIT同意),類似下面,

autoResetEvent.WaitOne(); 
await deviceClient.SendEventAsync(eventMessage); 
autoResetEvent.Set(); 

不要讓這個的AutoResetEvent全球化,所以,它的所有共享工作者線程。 PS:我看到你正試圖從一些Bmp180傳感器讀取數據,你可能想讓這些調用也是線程安全的。

讓我知道它是否適合你。