λР
Size: a a a
λР
λР
.ThrownExceptions
, .IsExecuting
и RxApp.DefaultExceptionHandler
RS
λР
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