WPF 中的 ReactiveCommand 通过订阅抛出异常

ReactiveCommand in WPF throws exception with Subscribe

我有一个带有 ReactiveUI 的简单演示应用程序:

//in the viewmodel
class MainViewModel : ReactiveObject
{
    public ReactiveUI.ReactiveCommand<Unit, Unit> MyReactiveCommand { get; }

    public MainViewModel()
    {
        MyReactiveCommand = ReactiveCommand.Create(() => { MessageBox.Show("Hello"); }, outputScheduler: RxApp.MainThreadScheduler);
    }
}

在视图中XAML

<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>

<Grid>
    <WrapPanel HorizontalAlignment = "Left">
        <Button Content="button" Command="{Binding MyReactiveCommand}"/>
    </WrapPanel>
</Grid>

当您按下按钮时,应该会出现一个消息框,但我却收到以下错误:

System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'

我试过返回一个值,然后按照 Glenn 的建议进行订阅,但遇到了同样的问题。至少使用此代码,消息框会在崩溃前打开 ;)

public class MainViewModel : ReactiveObject
{
    public ReactiveCommand<Unit, Unit> MyReactiveCommand { get; }

    public MainViewModel()
    {
        MyReactiveCommand = ReactiveCommand.CreateFromObservable(DoSometing);
        MyReactiveCommand.Subscribe(x => { MessageBox.Show("Hello"); });
    }

    public IObservable<Unit> DoSometing()
    {
        return Observable.Start(() => { });
    }
}

有几件事需要注意。 ReactiveCommand.CreateFromObservable 有一个名为 outputScheduler 的参数,这将是订阅输出的目标。你可以在这里传递RxApp.MainThreadScheduler

public class MainViewModel : ReactiveObject
{
    public ReactiveCommand<Unit, Unit> MyReactiveCommand { get; }

    public MainViewModel()
    {
        MyReactiveCommand = ReactiveCommand.CreateFromObservable(DoSometing, outputScheduler: RxApp.MainThreadScheduler);
        MyReactiveCommand.Subscribe(x => { MessageBox.Show("Hello"); });
    }

    public IObservable<Unit> DoSometing()
    {
        return Observable.Start(() => { });
    }
}

还要注意确保你已经安装了 NuGet 包 ReactiveUI.WPF