使用 ReactiveUI 按顺序执行一组命令
Execute a set of commands in order, sequentially with ReactiveUI
我有一个 ViewModel
,其中一些 ReactiveCommands
用户可以手动调用。
CommandA
CommandB
CommandC
所以用户只能调用B,或者先调用A,再调用C .
问题是我想创建另一个命令运行按顺序从A到C排列它们。它们不应该运行 并行,但 顺序 .
如何执行给定特征的命令?
我假设你的命令是 ReactiveCommand<Unit,Unit>
类型,所以你可以这样做:
public class MyCoolViewModel
{
bool runSequentially = false;
public ReactiveCommand<Unit, Unit> Command { get; set; }
public ReactiveCommand<Unit, Unit> Command2 { get; set; }
public ReactiveCommand<Unit, Unit> Command3 { get; set; }
public ReactiveCommand<Unit, Unit> CommandwhoInvokesOtherCommands { get; set; }
public MyCoolViewModel()
{
Command = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
runSequentially= false;
Console.WriteLine("Start 1");
await Task.Delay(1000);
Console.WriteLine("End 1");
return Unit.Default;
});
Command2 = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
runSequentially = false;
Console.WriteLine("Start 2");
await Task.Delay(1000);
Console.WriteLine("End 2");
return Unit.Default;
});
Command3 = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
Console.WriteLine("Start 3");
await Task.Delay(1000);
Console.WriteLine("End 3");
return Unit.Default;
});
CommandwhoInvokesOtherCommands = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
Console.WriteLine("Invoking other commands");
runSequentially = true;
await Task.Delay(1000);
Console.WriteLine("End");
return Unit.Default;
});
/*Command 1, 2 and 3 only will run if flag is set to true*/
CommandwhoInvokesOtherCommands.Where(_ => runSequentially).InvokeCommand(Command);
Command.Where(_ => runSequentially).InvokeCommand(Command2);
Command2.Where(_ => runSequentially).InvokeCommand(Command3);
//Observable.Return(Unit.Default).InvokeCommand(CommandwhoInvokesOtherCommands);//for test purposes
}
}
实用方法 InvokeCommand 会在一个命令 returns 时调用另一个命令,所以这个方法加上一个 where 子句就可以了。
希望对你有帮助
问候
由于您希望它们按顺序执行,ReactiveCommand.CreateCombined
isn't really a good fit. However, you could create something similar to CombinedReactiveCommand 适合您的情况。
响应式命令可以通过调用 ReactiveCommand<TParam,TResult>.Execute
手动执行,其中 returns 和 IObservable<TResult>
returns 单个值。因此,一个非常基本的实现可以将它链接到其他执行调用 SelectMany
:
ReactiveCommand.CreateFromObservable(() =>
CommandA.Execute()
.SelectMany(_ => CommandB.Execute())
.SelectMany(_ => CommandC.Execute()));
如果您的所有命令都具有相同的类型,它可以变得更通用:
var commands = new[] { CommandA, CommandB, CommandC };
ReactiveCommand.CreateFromObservable(() =>
commands.Aggregate(
Observable.Return(Unit.Default),
(acc, cur) => acc.SelectMany(_ => cur.Execute())));
然而,这并没有考虑 CombinedReactiveCommand 处理的其他事情,例如 CanExecute
和 ThrownExceptions
。如果您需要处理这些,那么您可以考虑推出自己的 CombinedReactiveCommand。
导入System.Reactive.Linq,现在您可以:
{
await CommandA.Execute();
await CommandB.Execute();
await CommandC.Execute();
}
System.Reactive.Linq 使 IObservable 成为可等待的。
我有一个 ViewModel
,其中一些 ReactiveCommands
用户可以手动调用。
CommandA
CommandB
CommandC
所以用户只能调用B,或者先调用A,再调用C .
问题是我想创建另一个命令运行按顺序从A到C排列它们。它们不应该运行 并行,但 顺序 .
如何执行给定特征的命令?
我假设你的命令是 ReactiveCommand<Unit,Unit>
类型,所以你可以这样做:
public class MyCoolViewModel
{
bool runSequentially = false;
public ReactiveCommand<Unit, Unit> Command { get; set; }
public ReactiveCommand<Unit, Unit> Command2 { get; set; }
public ReactiveCommand<Unit, Unit> Command3 { get; set; }
public ReactiveCommand<Unit, Unit> CommandwhoInvokesOtherCommands { get; set; }
public MyCoolViewModel()
{
Command = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
runSequentially= false;
Console.WriteLine("Start 1");
await Task.Delay(1000);
Console.WriteLine("End 1");
return Unit.Default;
});
Command2 = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
runSequentially = false;
Console.WriteLine("Start 2");
await Task.Delay(1000);
Console.WriteLine("End 2");
return Unit.Default;
});
Command3 = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
Console.WriteLine("Start 3");
await Task.Delay(1000);
Console.WriteLine("End 3");
return Unit.Default;
});
CommandwhoInvokesOtherCommands = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
Console.WriteLine("Invoking other commands");
runSequentially = true;
await Task.Delay(1000);
Console.WriteLine("End");
return Unit.Default;
});
/*Command 1, 2 and 3 only will run if flag is set to true*/
CommandwhoInvokesOtherCommands.Where(_ => runSequentially).InvokeCommand(Command);
Command.Where(_ => runSequentially).InvokeCommand(Command2);
Command2.Where(_ => runSequentially).InvokeCommand(Command3);
//Observable.Return(Unit.Default).InvokeCommand(CommandwhoInvokesOtherCommands);//for test purposes
}
}
实用方法 InvokeCommand 会在一个命令 returns 时调用另一个命令,所以这个方法加上一个 where 子句就可以了。
希望对你有帮助 问候
由于您希望它们按顺序执行,ReactiveCommand.CreateCombined
isn't really a good fit. However, you could create something similar to CombinedReactiveCommand 适合您的情况。
响应式命令可以通过调用 ReactiveCommand<TParam,TResult>.Execute
手动执行,其中 returns 和 IObservable<TResult>
returns 单个值。因此,一个非常基本的实现可以将它链接到其他执行调用 SelectMany
:
ReactiveCommand.CreateFromObservable(() =>
CommandA.Execute()
.SelectMany(_ => CommandB.Execute())
.SelectMany(_ => CommandC.Execute()));
如果您的所有命令都具有相同的类型,它可以变得更通用:
var commands = new[] { CommandA, CommandB, CommandC };
ReactiveCommand.CreateFromObservable(() =>
commands.Aggregate(
Observable.Return(Unit.Default),
(acc, cur) => acc.SelectMany(_ => cur.Execute())));
然而,这并没有考虑 CombinedReactiveCommand 处理的其他事情,例如 CanExecute
和 ThrownExceptions
。如果您需要处理这些,那么您可以考虑推出自己的 CombinedReactiveCommand。
导入System.Reactive.Linq,现在您可以:
{
await CommandA.Execute();
await CommandB.Execute();
await CommandC.Execute();
}
System.Reactive.Linq 使 IObservable 成为可等待的。