public void BindToIsNotFooledByIntermediateObjectSwitching() { new TestScheduler().With(sched => { var input = new ScheduledSubject <string>(sched); var fixture = new HostTestFixture { Child = new TestFixture() }; input.BindTo(fixture, x => x.Child.IsNotNullString); Assert.Null(fixture.Child.IsNotNullString); input.OnNext("Foo"); sched.Start(); Assert.Equal("Foo", fixture.Child.IsNotNullString); fixture.Child = new TestFixture(); sched.Start(); Assert.Equal("Foo", fixture.Child.IsNotNullString); input.OnNext("Bar"); sched.Start(); Assert.Equal("Bar", fixture.Child.IsNotNullString); }); }
void marshalFailures <T>(Action <T> block, T param) { try { block(param); } catch (Exception ex) { _exSubject.OnNext(ex); } }
internal void notifyObservable <T>(T item, Subject <T> subject) { try { subject.OnNext(item); } catch (Exception ex) { this.Log().ErrorException("ReactiveObject Subscriber threw exception", ex); thrownExceptions.OnNext(ex); } }
public IObservable <TResult> RegisterAsyncObservable <TResult>(Func <object, IObservable <TResult> > calculationFunc) { Contract.Requires(calculationFunc != null); var ret = _executeSubject .Select(x => { AsyncStartedNotification.OnNext(Unit.Default); return(calculationFunc(x) .Catch <TResult, Exception>(ex => { _exSubject.OnNext(ex); return Observable.Empty <TResult>(); }) .Finally(() => AsyncCompletedNotification.OnNext(Unit.Default))); }); return(ret.Merge().Multicast(new ScheduledSubject <TResult>(RxApp.DeferredScheduler)).PermaRef()); }
public void BindToSmokeTest() { (new TestScheduler()).With(sched => { var input = new ScheduledSubject<string>(sched); var fixture = new HostTestFixture() {Child = new TestFixture()}; input.BindTo(fixture, x => x.Child.IsNotNullString); Assert.Null(fixture.Child.IsNotNullString); input.OnNext("Foo"); sched.Start(); Assert.Equal("Foo", fixture.Child.IsNotNullString); input.OnNext("Bar"); sched.Start(); Assert.Equal("Bar", fixture.Child.IsNotNullString); }); }
public ReactiveCommand(IObservable <bool> canExecute, bool allowsConcurrentExecution, IScheduler scheduler, bool initialCondition = true) { canExecute = canExecute ?? Observable.Return(true); defaultScheduler = scheduler ?? RxApp.MainThreadScheduler; AllowsConcurrentExecution = allowsConcurrentExecution; canExecute = canExecute.Catch <bool, Exception>(ex => { exceptions.OnNext(ex); return(Observable.Empty <bool>()); }); ThrownExceptions = exceptions = new ScheduledSubject <Exception>(defaultScheduler, RxApp.DefaultExceptionHandler); var isExecuting = inflight .Scan(0, (acc, x) => acc + (x ? 1 : -1)) .Select(x => x > 0) .Publish(false) .PermaRef() .DistinctUntilChanged(); IsExecuting = isExecuting.ObserveOn(defaultScheduler); var isBusy = allowsConcurrentExecution ? Observable.Return(false) : isExecuting; var canExecuteAndNotBusy = Observable.CombineLatest(canExecute, isBusy, (ce, b) => ce && !b); var canExecuteObs = canExecuteAndNotBusy .Publish(initialCondition) .RefCount(); CanExecuteObservable = canExecuteObs .DistinctUntilChanged() .ObserveOn(defaultScheduler); innerDisp = canExecuteObs.Subscribe(x => { if (canExecuteLatest == x) { return; } canExecuteLatest = x; defaultScheduler.Schedule(() => this.raiseCanExecuteChanged(EventArgs.Empty)); }, exceptions.OnNext); }
public void DisposingDisconnectsTheBindTo() { (new TestScheduler()).With(sched => { var input = new ScheduledSubject<string>(sched); var fixture = new HostTestFixture() {Child = new TestFixture()}; var subscription = input.BindTo(fixture, x => x.Child.IsNotNullString); Assert.Null(fixture.Child.IsNotNullString); input.OnNext("Foo"); sched.Start(); Assert.Equal("Foo", fixture.Child.IsNotNullString); subscription.Dispose(); input.OnNext("Bar"); sched.Start(); Assert.Equal("Foo", fixture.Child.IsNotNullString); }); }
public void BindToSmokeTest() { (new TestScheduler()).With(sched => { var input = new ScheduledSubject <string>(sched); var fixture = new HostTestFixture() { Child = new TestFixture() }; input.BindTo(fixture, x => x.Child.IsNotNullString); Assert.Null(fixture.Child.IsNotNullString); input.OnNext("Foo"); sched.Start(); Assert.Equal("Foo", fixture.Child.IsNotNullString); input.OnNext("Bar"); sched.Start(); Assert.Equal("Bar", fixture.Child.IsNotNullString); }); }
private async Task InitializeAsyncCore() { try { IsBusy = true; _asyncNavigating.OnNext(true); await Initialize().ConfigureAwait(false); } catch (Exception ex) { _thrownExceptions.OnNext(ex); } finally { _asyncNavigating.OnNext(false); IsBusy = false; } // configure BusyObservables after Initialize call, since sub-classes may create instances that contribute to IsBusy // during initialization. await Observable.Start(() => { BusyObservables .Select(o => o.StartWith(false)) .Concat(new[] { _asyncNavigating.StartWith(false) }) .Select(o => o.StartWith(false)) .CombineLatest() .Select(bs => bs.Any(b => b)) .Do(b => IsBusy = b) .Catch <bool, Exception>(ex => { _thrownExceptions.OnNext(ex); return(Observable.Return(false)); }) .Subscribe(); }, RxApp.MainThreadScheduler).ToTask(); }
public void BindToIsNotFooledByIntermediateObjectSwitching() { (new TestScheduler()).With(sched => { var input = new ScheduledSubject<string>(sched); var fixture = new HostTestFixture() {Child = new TestFixture()}; var subscription = input.BindTo(fixture, x => x.Child.IsNotNullString); Assert.Null(fixture.Child.IsNotNullString); input.OnNext("Foo"); sched.Start(); Assert.Equal("Foo", fixture.Child.IsNotNullString); fixture.Child = new TestFixture(); sched.Start(); Assert.Null(fixture.Child.IsNotNullString); input.OnNext("Bar"); sched.Start(); Assert.Equal("Bar", fixture.Child.IsNotNullString); }); }
public void DisposingDisconnectsTheBindTo() { new TestScheduler().With(sched => { var input = new ScheduledSubject <string>(sched); var fixture = new HostTestFixture { Child = new TestFixture() }; var subscription = input.BindTo(fixture, x => x.Child.IsNotNullString); Assert.Null(fixture.Child.IsNotNullString); input.OnNext("Foo"); sched.Start(); Assert.Equal("Foo", fixture.Child.IsNotNullString); subscription.Dispose(); input.OnNext("Bar"); sched.Start(); Assert.Equal("Foo", fixture.Child.IsNotNullString); }); }
/// <summary> /// Initializes a new instance of the <see cref="CombinedReactiveCommand{TParam, TResult}"/> class. /// </summary> /// <param name="childCommands">The child commands which will be executed.</param> /// <param name="canExecute">A observable when the command can be executed.</param> /// <param name="outputScheduler">The scheduler where to dispatch the output from the command.</param> /// <param name="canExecuteScheduler"> /// An optional scheduler that is used for CanExecute and IsExecuting events. Defaults to <c>RxApp.MainThreadScheduler</c>. /// </param> /// <exception cref="ArgumentNullException">Fires when required arguments are null.</exception> /// <exception cref="ArgumentException">Fires if the child commands container is empty.</exception> protected internal CombinedReactiveCommand( IEnumerable <ReactiveCommandBase <TParam, TResult> > childCommands, IObservable <bool> canExecute, IScheduler outputScheduler, IScheduler canExecuteScheduler) { if (childCommands is null) { throw new ArgumentNullException(nameof(childCommands)); } if (canExecute is null) { throw new ArgumentNullException(nameof(canExecute)); } if (outputScheduler is null) { throw new ArgumentNullException(nameof(outputScheduler)); } if (canExecuteScheduler is null) { throw new ArgumentNullException(nameof(canExecuteScheduler)); } var childCommandsArray = childCommands.ToArray(); if (childCommandsArray.Length == 0) { throw new ArgumentException("No child commands provided.", nameof(childCommands)); } _exceptions = new ScheduledSubject <Exception>(outputScheduler, RxApp.DefaultExceptionHandler); var canChildrenExecute = childCommandsArray.Select(x => x.CanExecute) .CombineLatest() .Select(x => x.All(y => y)); var combinedCanExecute = canExecute .Catch <bool, Exception>(ex => { _exceptions.OnNext(ex); return(Observables.False); }) .StartWith(false) .CombineLatest(canChildrenExecute, (ce, cce) => ce && cce) .DistinctUntilChanged() .Replay(1) .RefCount() .ObserveOn(canExecuteScheduler); _exceptionsSubscription = childCommandsArray.Select(x => x.ThrownExceptions) .Merge() .Subscribe(ex => _exceptions.OnNext(ex)); _innerCommand = new ReactiveCommand <TParam, IList <TResult> >( param => childCommandsArray .Select(x => x.Execute(param)) .CombineLatest(), combinedCanExecute, outputScheduler, canExecuteScheduler); // we already handle exceptions on individual child commands above, but the same exception // will tick through innerCommand. Therefore, we need to ensure we ignore it or the default // handler will execute and the process will be torn down _innerCommand .ThrownExceptions .Subscribe(); CanExecute.Subscribe(OnCanExecuteChanged); }
public void Execute(object parameter) { this.Log().InfoFormat("{0:X}: Executed", this.GetHashCode()); _executeSubject.OnNext(parameter); }