示例#1
0
        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);
            });
        }
示例#6
0
        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);
            });
        }
示例#9
0
        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);
            });
        }
示例#11
0
        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);
    }
示例#13
0
 public void Execute(object parameter)
 {
     this.Log().InfoFormat("{0:X}: Executed", this.GetHashCode());
     _executeSubject.OnNext(parameter);
 }