λР
Size: a a a
λР
λР
.ThrownExceptions, .IsExecuting и RxApp.DefaultExceptionHandlerRS
λР
try catch не писатьRS
λР
λР
λР
λР
λР
// IObservable<bool>
var canExecute =
this.WhenAnyValue(x => x.UserName)
.Select(name => !string.IsNullOrWhiteSpace(name))
.CombineLatest(background.IsExecuting,
(valid, executing) => valid && executing);
// ICommand
var command = ReactiveCommand.CreateFromTask(
DoStuffAsync,
canExecute)
λР
WhenAnyValue(x => x.UserName) слушает изменения св-ва UserName (превращает string в IObservable<string>), background.IsExecuting возвращает IObservable<bool>, который эмитит true если фоновая операция выполняется и false если не, и вдобавок ReactiveCommand выключит кнопку, пока выполняется DoStuffAsyncλР
event, метод-обработчик, штучки 3 флага-индикатора (один обновляется из метода-обработчика, другой обновляется из сеттера UserName, третий обновляется когда запускается или останавливается таска из DoStuffAsync) и делать Dispatcher.Invoke в некоторых местахλР
DoStuffAsync держать try {} catch {}λР
// IObservable<bool>
var canExecute =
this.WhenAnyValue(x => x.UserName)
.Select(name => !string.IsNullOrWhiteSpace(name))
.CombineLatest(background.IsExecuting,
(valid, executing) => valid && executing);
// ICommand
var command = ReactiveCommand.CreateFromTask(
DoStuffAsync,
canExecute)
command.ThrownExceptions или RxApp.DefaultExceptionHandler (это похоже на миддлвару в контексте ASP .NET Core, в которую валятся все ошибки, и которые можно обработать или залогировать, чтобы не развалиться)λР
λР
// IObservable<bool>
var canExecute =
this.WhenAnyValue(x => x.UserName)
.Select(name => !string.IsNullOrWhiteSpace(name))
.CombineLatest(background.IsExecuting,
(valid, executing) => valid && executing);
// ICommand
var command = ReactiveCommand.CreateFromTask(
DoStuffAsync,
canExecute)
Select и CombineLatest стали привычными, надо осилить LINQ (CombineLatest ~ Zip но, так сказать, с более частыми уведомлениями)λР
RS
λР
RS