Raspberry Pi の下で実行される XAML を使用して、ユニバーサル Windows プラットフォーム アプリを開発していWindows 10 IoT Core
ます。アプリは、I2C バス上の温度センサーを駆動します。センサークラスはMLX90614Thermometer
. センサーは aDispatcherTimer
を使用して 100 ミリ秒 (約) ごとに読み取り値を取得し、移動平均を更新します。移動平均の値が指定されたしきい値を超えて変化すると、センサーはイベントを発生させValueChanged
、イベント引数に新しい値を提供します。
私の ViewModel クラス ではTemperatureSensorViewModel
、センサーのイベントをサブスクライブし、それを使用して、およびValueChanged
という名前のバインドされたプロパティを更新します。これらのプロパティは、XAML UI のテキスト ブロックにバインドされています。イベント ハンドラは次のとおりです。Ambient
Channel1
Channel2
void HandleSensorValueChanged(object sender, SensorValueChangedEventArgs e)
{
switch (e.Channel)
{
case 0:
Ambient = e.Value;
break;
case 1:
Channel1 = e.Value;
break;
case 2:
Channel2 = e.Value;
break;
}
}
Ambient
...そして、これは...のサンプル データ バインディングです。
<TextBlock x:Name="Ambient" Grid.Row="1" Text="{Binding Path=Ambient}" Style="{StaticResource FieldValueStyle}" />
私はMVVM Light Toolkitを使用しているため、プロパティは次のように実装されています (Ambient
表示されているだけですが、名前以外は同じです)。
public double Ambient
{
get { return ambientTemperature; }
private set { Set(nameof(Ambient), ref ambientTemperature, value); }
}
MVVM Light Toolkit は、設定されているプロパティの通知Set()
を自動的に発生させるメソッドを提供します。PropertyChanged
ボタンの押下に応答してセンサーから単一のサンプルを読み取った場合、これは正しく機能します。ただし、自動サンプリング モード (タイマー ベース) を有効にするとすぐに、スローが開始されますCOMExceptions
。したがって、これはタイマーに関連するある種のスレッドの問題である必要があります。
ここで、私の理解が正しければ、ランタイムはPropertyChanged
通知を UI スレッドに自動的にマーシャリングすることになっています。スタック トレースを見ると、そのように見えます。しかし、最終的にはCOMException
. うーん。
System.Runtime.InteropServices.COMException (0x8001010E): アプリケーションは、別のスレッド用にマーシャリングされたインターフェイスを呼び出しました。(HRESULT からの例外: 0x8001010E (RPC_E_WRONG_THREAD)) System.Runtime.InteropServices.WindowsRuntime.PropertyChangedEventArgsMarshaler.ConvertToNative (PropertyChangedEventArgs managedArgs) で System.ComponentModel.PropertyChangedEventHandler.Invoke (オブジェクトの送信者、PropertyChangedEventArgs e) で GalaSoft.MvvmLight.ObservableObject.RaisePropertyChanged (文字列プロパティ名) で GalaSoft.MvvmLight.ViewModelBase.RaisePropertyChanged[T] (文字列 propertyName、T oldValue、T newValue、ブール値ブロードキャスト) で GalaSoft.MvvmLight.ViewModelBase.Set[T] (文字列 propertyName、T& フィールド、T newValue、ブール値ブロードキャスト) で TA.UWP.Devices.Samples.ViewModel.TemperatureSensorViewModel.set_Channel1 で (2 倍の値) TA.UWP.Devices.Samples.ViewModel.TemperatureSensorViewModel.HandleSensorValueChanged (オブジェクト送信者、SensorValueChangedEventArgs e) で at TA.UWP.Devices.MLX90614Thermometer.RaiseValueChanged(UInt32 チャネル、Double 値) TA.UWP.Devices.MLX90614Thermometer.SampleAllChannels() で TA.UWP.Devices.MLX90614Thermometer.b__37_0() で System.Threading.Tasks.Task.InnerInvoke() で System.Threading.Tasks.Task.Execute() で --- 例外がスローされた前の場所からのスタック トレースの終わり --- System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (タスク タスク) で System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (タスク タスク) で System.Runtime.CompilerServices.TaskAwaiter.GetResult() で TA.UWP.Devices.MLX90614Thermometer.d__37.MoveNext() で --- 例外がスローされた前の場所からのスタック トレースの終わり --- System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (タスク タスク) で System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (タスク タスク) で System.Runtime.CompilerServices.TaskAwaiter.GetResult() で TA.UWP.Devices.MLX90614Thermometer.d__38.MoveNext() で
何?ここで何が起こっているのかわかりません。誰が問題が何であるかを見ることができますか?