public AppModel() { SwitchDevice = ObservableProperty.CreateSettable <object>(null, true); ReverseBitmap = ObservableProperty.CreateSettable <object>(null, true); VideoBitmap = ObservableProperty.CreateSettable <BitmapFrame>(null); IsRunning = ObservableProperty.CreateSettable(false); var oldNewIndexes = SwitchDevice .Select(_ => new { OldValue = SelectedDeviceIndex.Value, NewValue = (SelectedDeviceIndex.Value + 1) % _devices.Length }) .ToGetOnly(null); SelectedDeviceIndex = oldNewIndexes .Select(_ => _.NewValue) .ToGetOnly(0); BitmapScaleX = ReverseBitmap .Select(_ => - 1 * BitmapScaleX.Value) .ToGetOnly(-1); _devices = new FilterInfoCollection(FilterCategory.VideoInputDevice) .Cast <FilterInfo>() .Select(f => new VideoCaptureDevice(f.MonikerString)) .Do(d => d.VideoResolution = GetResolution(d.VideoCapabilities)) .ToArray(); if (_devices.Length == 0) { return; } IsRunning //.Throttle(TimeSpan.FromMilliseconds(200)) .ObserveOn(Scheduler.Default) .Subscribe(b => { if (b) { StartDevice(SelectedDeviceIndex.Value); } else { StopDevice(SelectedDeviceIndex.Value); } }); oldNewIndexes .Where(_ => IsRunning.Value) //.Throttle(TimeSpan.FromMilliseconds(200)) .ObserveOn(Scheduler.Default) .Subscribe(_ => { StopDevice(_.OldValue); // 連続してデバイスを操作すると失敗することがあるため、待機します。 Thread.Sleep(200); StartDevice(_.NewValue); }); }