如何使用ReactiveCommand?

时间:2018-08-08 12:55:07

标签: mvvm reactiveui

我有一个使用ReactiveCommand的视图模型:

public ReactiveCommand<Unit, Unit> Command { get; }

public MyViewModel()
{
    Command = ReactiveCommand<Unit, Unit>.Create(MyMethod);
}

并将其绑定到按钮:

<DataTemplate>
    <Button Content="Press me" 
    Command="{Binding Command, Mode=OneTime}"
    Margin="0,0,5,0"/>
</DataTemplate>

我这样将视图绑定到viewmodel(对于我而言,这是最方便的方式):

myView.DataContext = new MyViewModel();

当我按下按钮MyMethod被执行时,并且在执行MyMethod中的最后一个运算符之后,我的应用程序崩溃了:

  

InvalidOperationException:调用线程无法访问此对象,因为另一个线程拥有它。

  StackTrace:
   at System.Windows.Threading.Dispatcher.VerifyAccess()
   at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
   at System.Windows.Controls.Primitives.ButtonBase.get_Command()
   at System.Windows.Controls.Primitives.ButtonBase.UpdateCanExecute()
   at System.Windows.Controls.Primitives.ButtonBase.OnCanExecuteChanged(Object sender, EventArgs e)
   at System.Windows.Input.CanExecuteChangedEventManager.HandlerSink.OnCanExecuteChanged(Object sender, EventArgs e)
   at ReactiveUI.ReactiveCommand.OnCanExecuteChanged()
   at ReactiveUI.ReactiveCommand`2.<.ctor>b__9_6(Boolean _)
   at System.Reactive.AnonymousSafeObserver`1.OnNext(T value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\AnonymousSafeObserver.cs:line 54
   at System.Reactive.Linq.ObservableImpl.RefCount`1._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\RefCount.cs:line 66
   at System.Reactive.Subjects.FastImmediateObserver`1.EnsureActive(Int32 count) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\ReplaySubject.cs:line 893
   at System.Reactive.Subjects.FastImmediateObserver`1.EnsureActive() in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\ReplaySubject.cs:line 753
   at System.Reactive.Subjects.ReplaySubject`1.ReplayBase.OnNext(T value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\ReplaySubject.cs:line 276
   at System.Reactive.Subjects.ReplaySubject`1.OnNext(T value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\ReplaySubject.cs:line 167
   at System.Reactive.Linq.ObservableImpl.AsObservable`1._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\AsObservable.cs:line 32
   at System.Reactive.Linq.ObservableImpl.DistinctUntilChanged`2._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\DistinctUntilChanged.cs:line 79
   at System.Reactive.Linq.ObservableImpl.CombineLatest`3._.SecondObserver.OnNext(TSecond value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\CombineLatest.cs:line 189
   at System.Reactive.Linq.ObservableImpl.RefCount`1._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\RefCount.cs:line 66
   at System.Reactive.Subjects.FastImmediateObserver`1.EnsureActive(Int32 count) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\ReplaySubject.cs:line 893
   at System.Reactive.Subjects.FastImmediateObserver`1.EnsureActive() in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\ReplaySubject.cs:line 753
   at System.Reactive.Subjects.ReplaySubject`1.ReplayBase.OnNext(T value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\ReplaySubject.cs:line 276
   at System.Reactive.Subjects.ReplaySubject`1.OnNext(T value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\ReplaySubject.cs:line 167
   at System.Reactive.Linq.ObservableImpl.AsObservable`1._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\AsObservable.cs:line 32
   at System.Reactive.Linq.ObservableImpl.DistinctUntilChanged`2._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\DistinctUntilChanged.cs:line 79
   at System.Reactive.Linq.ObservableImpl.Concat`1._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\Concat.cs:line 34
   at System.Reactive.Linq.ObservableImpl.Select`2.Selector._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\Select.cs:line 49
   at System.Reactive.Linq.ObservableImpl.Scan`2._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\Scan.cs:line 50
   at System.Reactive.SafeObserver`1.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Internal\SafeObserver.cs:line 50
   at System.Reactive.ScheduledObserver`1.Dispatch(ICancelable cancel) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Internal\ScheduledObserver.cs:line 93
   at System.Reactive.Concurrency.Scheduler.<>c.<ScheduleLongRunning>b__73_0(Action`1 a, ICancelable c) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Concurrency\Scheduler.Simple.cs:line 78
   at System.Reactive.Concurrency.DefaultScheduler.LongRunning.<>c__DisplayClass1_0`1.<ScheduleLongRunning>b__0(Object arg) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Concurrency\DefaultScheduler.cs:line 165
   at System.Reactive.Concurrency.ConcurrencyAbstractionLayerImpl.<>c__DisplayClass7_0.<StartThread>b__0() in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Concurrency\ConcurrencyAbstractionLayerImpl.cs:line 56
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

我使用ReactiveCommand是错误的还是ReactiveUI中的错误?

我能够在仅使用空方法调用ReactiveCommand的最小WPF应用程序中重现此错误。

1 个答案:

答案 0 :(得分:5)

我只需要安装ReactiveUI.WPF NuGet软件包。

真的希望为ReactiveUI提供更好的文档。