До и после действия для ReactiveCommand

Я хочу установить флаг занятости и текст строки состояния перед выполнением команды, а после ее завершения — сбросить флаг и текст. Мой рабочий код здесь:

Cmd = ReactiveCommand.Create();
Cmd.Subscribe(async _ => 
{
    IsBusy = true;
    StatusBarText = "Doing job...";
    try
    {
        var organization = await DoAsyncJob();
        //do smth w results
    }
    finally
    {
        IsBusy = false;
        StatusBarText = "Ready";
});

Можно ли это сделать "правильным образом"? Как это:

Cmd = ReactiveCommand.CreateAsyncTask(_ => DoAsyncJob());
//how to do pre-action?
//is exists more beautiful way to to post-action?
Cmd.Subscribe(res =>
{
    try
    {
        //do smth w results
    }
    finally
    {
        IsBusy = false;
        StatusBarText = "Ready";
    }
});

Или это:

Cmd = ReactiveCommand.CreateAsyncTask(_ => DoAsyncJob());
//is exists more beautiful way to to post-action?
Cmd.Do(_ => 
{
    IsBusy = true;
    StatusBarText = "Doing job...";
})
.Subscribe(res =>
{
    try
    {
        //do smth w results
    }
    finally
    {
        IsBusy = false;
        StatusBarText = "Ready";
    }
});

person Valery Plotnik    schedule 19.08.2014    source источник


Ответы (1)


Собственно, это уже встроено в ReactiveCommand:

Cmd = ReactiveCommand.CreateAsyncTask(_ => DoAsyncJob());
Cmd.IsExecuting.ToProperty(this, x => x.IsBusy, out isBusy);

Кроме того, никогда не пишите это:

someObservable.Subscribe(async _ => 

Subscribe не знает об асинхронности, его возвращаемое значение onNext равно void. Вместо этого напишите это:

someObservable.SelectMany(async _ => {...}).Subscribe(x => {...});

Вы можете поместить все, что хотите, в блок «Подписка», я обычно пишу что-то вроде заявления о регистрации.

person Ana Betts    schedule 19.08.2014
comment
Спасибо за ответ! Насколько я понимаю, IsExecuting (и ThrownExceptions) работает только с CreateAsyncTask. Я пытался использовать SelectMany, но когда он вызывает, IsExecuting уже имеет значение false. Я прочитал эту статью: ссылка и, насколько я понимаю, более применимый способ (где CmdImpl - что у меня в SelectMany): Cmd = ReactiveCommand.CreateAsyncTask(CmdImpl); Cmd.IsExecuting.Subscribe(b => IsBusy = b); Правильно ли я думаю? - person Valery Plotnik; 20.08.2014
comment
IsExecuting работает, только если вы используете CreateAsyncXYZ, правильно — если вы используете SelectMany вне Observable, команда не знает об этом. Вместо подписки и изменяемого значения я бы действительно попытался использовать ToProperty. - person Ana Betts; 20.08.2014
comment
Если мне нужно установить флаг занятости из нескольких команд, я должен сделать это следующим образом: this.WhenAnyObservable(vm => vm.Cmd1.IsExecuting, vm => vm.Cmd2.IsExecuting, ...).ToProperty(this, vm => vm.IsBusy, out isBusy); ? - person Valery Plotnik; 21.08.2014