通过 ReactiveCommand 运行 以意外顺序生成的事件

Events generated through ReactiveCommand run in unexpected order

我遇到了一个问题,在我希望所有事件都完成后,我看到事件 运行ning。但这只有在调用的方法被 ReactiveCommand 调用时才会发生。

我有一个视图模型,其中有一个 属性 和一个计算的 属性:

public class ViewModel : ReactiveObject
{
    private int _property;
    private readonly ObservableAsPropertyHelper<int> _calculatedProperty;

    public ViewModel()
    {
        Command = new DelegateCommand(x => Test("Command"));
        ReactiveCommand = ReactiveCommand.Create(() => Test("ReactiveCommand"));

        this.WhenAnyValue(x => x.Property)
            .Do(x => Console.WriteLine($"CalculatedProperty will be set to {x}"))
            .ToProperty(this, x => x.CalculatedProperty, out _calculatedProperty);
        this.WhenAnyValue(x => x.CalculatedProperty)
            .Subscribe(v => Console.WriteLine($"CalculatedProperty was set to {v}"));
    }

    public void Test(string method)
    {
        Console.WriteLine($"Begin {method}");
        Property++;
        Console.WriteLine($"End {method}");
    }

    public int Property
    {
        get => _property;
        set => this.RaiseAndSetIfChanged(ref _property, value);
    }

    public int CalculatedProperty => _calculatedProperty.Value;

    public ICommand Command { get; }
    public ReactiveCommand ReactiveCommand { get; }
}

我有一个带有 2 个按钮的 window,一个绑定到命令,一个绑定到 ReactiveCommand(还有一个按钮带有老式的点击处理程序,其行为与命令相同)。

当我点击命令按钮时,输出的文本如我所料:

Begin Command
CalculatedProperty will be set to 1
CalculatedProperty was set to 1
End Command

然而,当我点击 ReactiveCommand 按钮时,我得到了这个:

Begin ReactiveCommand
CalculatedProperty will be set to 2
End ReactiveCommand
CalculatedProperty was set to 2

计算得出的 属性 事件在结束消息 运行 之后触发。这会导致我的代码出现问题,我不明白为什么会这样。我一直在调查和尝试在 ReactiveCommand.Create 方法中发送调度程序,查看 SynchronizationContexts 但我的所有实验都没有成功。

为什么会发生这种情况,我该怎么做才能阻止它?

因为默认情况下,ReactiveCommand 会将命令发送到主线程调度程序 ReactiveCommand.Create(() => action)

您的 Delegate 命令只是 运行 直接执行,无需通过调度程序,这与 ImmediateScheduler 的功能类似。

您可以将 ImmediateScheduler.Default 传递给 ReactiveCommand.Create()

的第二个参数

我发现 ToProperty 方法也接受一个调度程序。当我更改:

.ToProperty(this, x => x.CalculatedProperty, out _calculatedProperty);

至:

.ToProperty(this, x => x.CalculatedProperty, out _calculatedProperty,
            scheduler: ImmediateScheduler.Instance);

它按我的预期工作。不确定这是预期行为还是某种错误。这当然出乎我的意料。