Ejemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ViewModelViewHost"/> class.
        /// </summary>
        public ViewModelViewHost()
        {
            _currentView  = new SerialDisposable();
            _viewContract = this
                            .WhenAnyObservable(x => x.ViewContractObservable !)
                            .ToProperty(this, x => x.ViewContract, initialValue: null, scheduler: RxApp.MainThreadScheduler);

            Initialize();
        }
Ejemplo n.º 2
0
        public ViewModelViewHost()
        {
            this.currentView  = new SerialDisposable();
            this.viewContract = this
                                .WhenAnyObservable(x => x.ViewContractObservable)
                                .ToProperty(this, x => x.ViewContract, scheduler: RxApp.MainThreadScheduler);

            this.Initialize();
        }
Ejemplo n.º 3
0
        public static void AssignSameTwiceDoesNotDispose()
        {
            using var serialDisposable = new SerialDisposable <IDisposable>();
            var mock = new Mock <IDisposable>(MockBehavior.Strict);

            serialDisposable.Disposable = mock.Object;
            serialDisposable.Disposable = mock.Object;
            mock.Setup(x => x.Dispose());
        }
Ejemplo n.º 4
0
        public ToDoItemView()
        {
            InitializeComponent();

            var disposable = new SerialDisposable();

            this.OnUpdated <ToDoItem>(viewModel =>
            {
                IDisposable buttonClick, userTyped;

                // TODO: need a cancel button here

                if (viewModel.IsEditable)
                {
                    editButton.Visibility = Visibility.Collapsed;
                    saveButton.Visibility = Visibility.Visible;

                    buttonClick = Observable.FromEventPattern <RoutedEventArgs>(saveButton, "Click")
                                  .Subscribe(_ => this.Dispatch(new SaveItemAction(viewModel.Id, edit.Text)));

                    userTyped =
                        edit.Events().KeyDown
                        .Where(x => x.Key == Key.Enter)
                        .SelectUnit()
                        .Subscribe(_ => this.Dispatch(new SaveItemAction(viewModel.Id, edit.Text)));

                    edit.Visibility = Visibility.Visible;
                    text.Visibility = Visibility.Collapsed;
                }
                else
                {
                    editButton.Visibility = Visibility.Visible;
                    saveButton.Visibility = Visibility.Collapsed;

                    buttonClick = Observable.FromEventPattern <RoutedEventArgs>(editButton, "Click")
                                  .Subscribe(_ => this.Dispatch(new EditItemAction(viewModel.Id)));

                    userTyped = Disposable.Empty;

                    edit.Visibility = Visibility.Collapsed;
                    text.Visibility = Visibility.Visible;
                }

                text.Text = viewModel.Text;
                edit.Text = viewModel.Text;

                isChecked.IsChecked = viewModel.IsComplete;

                var checkedChanged = isChecked.IsChecked == false
                    ? Observable.FromEventPattern <RoutedEventArgs>(isChecked, "Checked")
                                     .Subscribe(_ => this.Dispatch(new CheckedItemAction(viewModel.Id)))
                    : Observable.FromEventPattern <RoutedEventArgs>(isChecked, "Unchecked")
                                     .Subscribe(_ => this.Dispatch(new UncheckedItemAction(viewModel.Id)));

                disposable.Disposable = new CompositeDisposable(buttonClick, userTyped, checkedChanged);
            });
        }
        public MainViewModel(IDiagnosticsViewModel diagnosticsViewModel,
                             ITabularDataService tabularDataService,
                             IColumnsService columnsService,
                             IOverlayService overlayService,
                             IDateTimeService dateTimeService,
                             ISchedulerService schedulerService)
        {
            _tabularDataService = tabularDataService;
            _schedulerService   = schedulerService;
            _columnsService     = columnsService;
            _overlayService     = overlayService;
            _dateTimeService    = dateTimeService;
            Diagnostics         = diagnosticsViewModel;

            _dataIds        = new Dictionary <object, DynamicDataViewModel>(1000);
            _data           = new CustomTypeRangeObservableCollection <DynamicDataViewModel>();
            _collectionView = new ListCollectionView(_data)
            {
                Filter = FilterData
            };

            _updateStats = new Dictionary <long, int>();

            RefreshCommand = ReactiveCommand.Create()
                             .DisposeWith(this);

            ClearCommand = ReactiveCommand.Create()
                           .DisposeWith(this);

            ColumnPickerCommand = ReactiveCommand.Create(HasDataChanged)
                                  .DisposeWith(this);

            _dataStream = InitialiseAndProcessDataAsync()
                          .DisposeWith(this);

            RefreshCommand.Subscribe(x => Refresh())
            .DisposeWith(this);

            ClearCommand.Subscribe(x => Clear())
            .DisposeWith(this);

            ColumnPickerCommand.Subscribe(x => ShowColumnPicker())
            .DisposeWith(this);

            _suspendNotifications = new SerialDisposable()
                                    .DisposeWith(this);

            FilterChanged.Subscribe(x => _collectionView.Refresh())
            .DisposeWith(this);

            ColumnsChanged.ObserveOn(schedulerService.Dispatcher)
            .Subscribe(x => OnPropertyChanged(nameof(VisibleColumns)))
            .DisposeWith(this);

            Disposable.Create(() => Clear())
            .DisposeWith(this);
        }
        public override IDisposable Subscribe(IObserver <T[]> observer)
        {
            this.observer = observer;
            disposable    = _serialDisposable = new SerialDisposable();
            var group = _batched[_index];

            _serialDisposable.Disposable = group.Subscribe(this);
            return(_serialDisposable);
        }
Ejemplo n.º 7
0
 void Restart()
 {
     Debug.Log("Restart");
     disposable.Dispose();
     disposable            = new SerialDisposable();
     disposable.Disposable = Observable.Interval(TimeSpan.FromSeconds(interval)).Subscribe(_ =>
                                                                                           SendObsData()
                                                                                           ).AddTo(this);
 }
Ejemplo n.º 8
0
 public static Func <IDisposable> CreateAndDisposeOn(this Func <IDisposable> fn, IScheduler s)
 {
     return(() =>
     {
         var d = new SerialDisposable();
         s.Schedule(() => d.Disposable = fn());
         return d.DisposeOn(s);
     });
 }
Ejemplo n.º 9
0
 public Character(Dungeon _dungeon)
 {
     UniqueId                  = lastId++;
     ActionWait                = MAX_WAIT;
     dungeon                   = _dungeon;
     ReservedActions           = new List <CharacterAction>();
     spriteAnimationDisposable = new SerialDisposable();
     StatusEffects             = new List <CharacterStatusEffect>();
 }
Ejemplo n.º 10
0
            public IDisposable Run()
            {
                sourceSubscription            = new SingleAssignmentDisposable();
                timerSubscription             = new SerialDisposable();
                timerSubscription.Disposable  = RunTimer(objectId);
                sourceSubscription.Disposable = parent.source.Subscribe(this);

                return(StableCompositeDisposable.Create(timerSubscription, sourceSubscription));
            }
Ejemplo n.º 11
0
        public ComplexClass()
        {
            SerialDisposable = new SerialDisposable();
            MethodModel      = new ThreeMethodsWithMultipleSubscribesModel();
            Subject          = new Subject <string>();

            DisposableTestContainer.Add(
                this.WhenAnyValue(x => x.StringProperty).Subscribe());
        }
Ejemplo n.º 12
0
            public IDisposable Run()
            {
                tick       = new ThrottleFirstFrameTick(this);
                cancelable = new SerialDisposable();

                var subscription = parent.source.Subscribe(this);

                return(StableCompositeDisposable.Create(cancelable, subscription));
            }
Ejemplo n.º 13
0
        public static IObservable <TSource> CatchAndRetry <TSource, TException>(
            this IObservable <TSource> source,
            Func <TException /* error */, IObservable <TSource> /* originalSource */, int /* failureCount */, IObservable <TSource> > delayFactory,
            IScheduler scheduler = null
            )
            where TException : Exception
        {
            return(Observable.Create <TSource>(observer =>
            {
                scheduler = scheduler ?? Scheduler.CurrentThread;
                var originalScoure = source;
                var sourceDisposable = new SerialDisposable();
                int retryCount = 0;

                var scheduleDisposable = scheduler.Schedule(
                    self =>
                {
                    var oldSubscription = sourceDisposable.Disposable;
                    var newSubscription = source.Subscribe(
                        onNext: x => { observer.OnNext(x); if (retryCount > 0)
                                       {
                                           retryCount = 0;
                                       }
                        },
                        onError: ex =>
                    {
                        var typedException = ex as TException;
                        if (typedException != null)
                        {
                            source = delayFactory(typedException, originalScoure, ++retryCount);
                            if (source != null)
                            {
                                self();
                            }
                            else
                            {
                                observer.OnError(ex);
                            }
                        }
                        else
                        {
                            observer.OnError(ex);
                        }
                    },
                        onCompleted: observer.OnCompleted
                        );

                    if (sourceDisposable.Disposable == oldSubscription)
                    {
                        sourceDisposable.Disposable = newSubscription;
                    }
                });

                return new CompositeDisposable(scheduleDisposable, sourceDisposable);
            }));
        }
        /// <summary>
        /// Set the source URI of the image.
        /// </summary>
        /// <param name="view">The image view instance.</param>
        /// <param name="source">The source URI.</param>
        private async void SetUriFromSingleSource(Border view, string source)
        {
            var imageBrush = (ImageBrush)view.Background;
            var tag        = view.GetTag();

            var disposable = default(SerialDisposable);

            if (!_disposables.TryGetValue(tag, out disposable))
            {
                disposable = new SerialDisposable();
                _disposables.Add(tag, disposable);
            }

            var image = new BitmapImage();

            if (BitmapImageHelpers.IsBase64Uri(source))
            {
                image.BeginInit();
                image.CacheOption = BitmapCacheOption.OnLoad;

                disposable.Disposable = image.GetStreamLoadObservable().Subscribe(
                    status => OnImageStatusUpdate(view, status),
                    _ => OnImageFailed(view));

                var stream = BitmapImageHelpers.GetStreamAsync(source);
                image.StreamSource = stream;

                image.EndInit();
            }
            else
            {
                try
                {
                    var uri = new Uri(source);

                    image.BeginInit();
                    image.CacheOption = BitmapCacheOption.OnLoad;

                    if (uri.IsFile)
                    {
                        image.UriSource = uri;
                    }
                    else
                    {
                        await SetImageSourceFromUri(uri, image);
                    }

                    image.EndInit();
                }
                catch (Exception)
                {
                    image = null;
                }
            }
            imageBrush.ImageSource = image;
        }
Ejemplo n.º 15
0
        public static T DisposeWith <T>(this T obj, SerialDisposable serialDisposable)
        {
            var disposable = obj as IDisposable;

            if (disposable != null)
            {
                serialDisposable.Disposable = disposable;
            }
            return(obj);
        }
Ejemplo n.º 16
0
            public IDisposable Run()
            {
                list    = new List <T>();
                timerId = 0L;
                timerD  = new SerialDisposable();
                CreateTimer();
                IDisposable disposable = parent.source.Subscribe(this);

                return(StableCompositeDisposable.Create(disposable, timerD));
            }
Ejemplo n.º 17
0
            public IDisposable Run()
            {
                cancelable = new SerialDisposable();
                var subscription = parent.source.Subscribe(this);

                messageQueue = new Queue<T>(10);
                MainThreadDispatcher.SendStartCoroutine(TakeCoroutine());

                return StableCompositeDisposable.Create(cancelable, subscription);
            }
Ejemplo n.º 18
0
        protected override IDisposable SubscribeCore(IObserver <long> observer, IDisposable cancel)
        {
            var timerObserver = new Timer(observer, cancel);

            var dueTime = (dueTimeA != null)
                ? dueTimeA.Value - scheduler.Now
                : dueTimeB.Value;

            // one-shot
            if (period == null)
            {
                return(scheduler.Schedule(Scheduler.Normalize(dueTime), () =>
                {
                    timerObserver.OnNext();
                    timerObserver.OnCompleted();
                }));
            }
            else
            {
                var periodicScheduler = scheduler as ISchedulerPeriodic;
                if (periodicScheduler != null)
                {
                    if (dueTime == period.Value)
                    {
                        // same(Observable.Interval), run periodic
                        return(periodicScheduler.SchedulePeriodic(Scheduler.Normalize(dueTime), timerObserver.OnNext));
                    }
                    else
                    {
                        // Schedule Once + Scheudle Periodic
                        var disposable = new SerialDisposable();

                        disposable.Disposable = scheduler.Schedule(Scheduler.Normalize(dueTime), () =>
                        {
                            timerObserver.OnNext(); // run first

                            var timeP             = Scheduler.Normalize(period.Value);
                            disposable.Disposable = periodicScheduler.SchedulePeriodic(timeP, timerObserver.OnNext); // run periodic
                        });

                        return(disposable);
                    }
                }
                else
                {
                    var timeP = Scheduler.Normalize(period.Value);

                    return(scheduler.Schedule(Scheduler.Normalize(dueTime), self =>
                    {
                        timerObserver.OnNext();
                        self(timeP);
                    }));
                }
            }
        }
        /// <summary>
        /// Set the source URI of the image.
        /// </summary>
        /// <param name="view">The image view instance.</param>
        /// <param name="source">The source URI.</param>
        private async void SetUriFromSingleSource(Border view, string source)
        {
            var imageBrush = (ImageBrush)view.Background;
            var tag        = view.GetTag();

            var disposable = default(SerialDisposable);

            if (!_disposables.TryGetValue(tag, out disposable))
            {
                disposable = new SerialDisposable();
                _disposables.Add(tag, disposable);
            }

            if (BitmapImageHelpers.IsBase64Uri(source))
            {
                var image = new BitmapImage();

                disposable.Disposable = image.GetStreamLoadObservable().Subscribe(
                    status => OnImageStatusUpdate(view, status.LoadStatus, status.Metadata),
                    _ => OnImageFailed(view));

                using (var stream = await BitmapImageHelpers.GetStreamAsync(source))
                {
                    await image.SetSourceAsync(stream);
                }

                imageBrush.ImageSource = image;
            }
            else if (BitmapImageHelpers.IsHttpUri(source))
            {
                OnImageStatusUpdate(view, ImageLoadStatus.OnLoadStart, default(ImageMetadata));
                try
                {
                    var image = await ImageCache.Instance.GetFromCacheAsync(new Uri(source), true);

                    var metadata = new ImageMetadata(source, image.PixelWidth, image.PixelHeight);
                    OnImageStatusUpdate(view, ImageLoadStatus.OnLoad, metadata);
                    imageBrush.ImageSource = image;
                    OnImageStatusUpdate(view, ImageLoadStatus.OnLoadEnd, metadata);
                }
                catch
                {
                    OnImageFailed(view);
                }
            }
            else
            {
                var image = new BitmapImage();
                disposable.Disposable = image.GetUriLoadObservable().Subscribe(
                    status => OnImageStatusUpdate(view, status.LoadStatus, status.Metadata),
                    _ => OnImageFailed(view));
                image.UriSource        = new Uri(source);
                imageBrush.ImageSource = image;
            }
        }
Ejemplo n.º 20
0
        public void WhereIndex_DisposeInPredicate()
        {
            var scheduler = new TestScheduler();

            var invoked = 0;

            var xs = scheduler.CreateHotObservable(
                OnNext(110, 1),
                OnNext(180, 2),
                OnNext(230, 3),
                OnNext(270, 4),
                OnNext(340, 5),
                OnNext(380, 6),
                OnNext(390, 7),
                OnNext(450, 8),
                OnNext(470, 9),
                OnNext(560, 10),
                OnNext(580, 11),
                OnCompleted<int>(600),
                OnNext(610, 12),
                OnError<int>(620, new Exception()),
                OnCompleted<int>(630)
            );

            var res = scheduler.CreateObserver<int>();

            var d = new SerialDisposable();
            var ys = default(IObservable<int>);


            scheduler.ScheduleAbsolute(Created, () => ys = xs.Where((x, i) =>
            {
                invoked++;
                if (x == 8)
                    d.Dispose();
                return IsPrime(x + i * 10);
            }));

            scheduler.ScheduleAbsolute(Subscribed, () => d.Disposable = ys.Subscribe(res));

            scheduler.ScheduleAbsolute(Disposed, () => d.Dispose());

            scheduler.Start();

            res.Messages.AssertEqual(
                OnNext(230, 3),
                OnNext(390, 7)
            );

            xs.Subscriptions.AssertEqual(
                Subscribe(200, 450)
            );

            Assert.Equal(6, invoked);
        }
Ejemplo n.º 21
0
 public BubbleViewModel(int initialExponent, Vector2Int gridPosition)
 {
     _gridPosition         = new ReactiveProperty <Vector2Int>(gridPosition).AddTo(Disposer);
     _exponent             = new ReactiveProperty <int>(initialExponent).AddTo(Disposer);
     _isOnGrid             = new ReactiveProperty <bool>(true).AddTo(Disposer);
     _nextBubbleIndex      = new ReactiveProperty <int>(-1).AddTo(Disposer);
     _mergeTarget          = new ReactiveProperty <Vector2Int>(new Vector2Int(-1, -1)).AddTo(Disposer);
     _serialDisposable     = new SerialDisposable().AddTo(Disposer);
     _isConnectedToCeiling = new ReactiveProperty <bool>().AddTo(Disposer);
     _neighborAdded        = new ReactiveProperty <Vector2Int>().AddTo(Disposer);
 }
        public GoogleDriveExerciseDocumentService(
            IConnectionResultHandler connectionResultHandler)
        {
            Ensure.ArgumentNotNull(connectionResultHandler, nameof(connectionResultHandler));

            this.logger = LoggerService.GetLogger(this.GetType());
            this.connectionResultHandler = connectionResultHandler;
            this.exerciseDocument        = new BehaviorSubject <string>(null);
            this.sync = new object();
            this.connectedDisposable = new SerialDisposable();
        }
Ejemplo n.º 23
0
        public static IDisposable BindTo(this IObservable <bool> This, IInputLayer inputLayer, string reason)
        {
            var disableDisposable = new SerialDisposable();

            return(new CompositeDisposable(
                       disableDisposable,
                       This.DistinctUntilChanged()
                       .Subscribe(x => disableDisposable.Disposable = x
                        ? null
                        : inputLayer.Disable(reason))));
        }
Ejemplo n.º 24
0
        public IDisposable Schedule <TState>(TState state, Func <IScheduler, TState, IDisposable> action)
        {
            bool isCancelled = false;
            var  innerDisp   = new SerialDisposable {
                Disposable = Disposable.Empty
            };

            try
            {
                if (looperId > 0 && looperId == Java.Lang.Thread.CurrentThread().Id)
                {
                    return(action(this, state));
                }
            }
            catch (Exception exception)
            {
                analyticsService.DebugScheduleError.Track(nameof(HandlerScheduler), "Schedule:1:1", exception.GetType().Name, exception.StackTrace);
                analyticsService.Track(exception, exception.Message);
                throw;
            }

            try
            {
                handler.Post(() =>
                {
                    if (isCancelled)
                    {
                        return;
                    }

                    try
                    {
                        innerDisp.Disposable = action(this, state);
                    }
                    catch (Exception exception)
                    {
                        analyticsService.DebugScheduleError.Track(nameof(HandlerScheduler), "Schedule:1:2", exception.GetType().Name, exception.StackTrace);
                        analyticsService.Track(exception, exception.Message);
                        throw;
                    }
                });
            }
            catch (Exception exception)
            {
                analyticsService.DebugScheduleError.Track(nameof(HandlerScheduler), "Schedule:1:3", exception.GetType().Name, exception.StackTrace);
                analyticsService.Track(exception, exception.Message);
                throw;
            }

            return(new CompositeDisposable(
                       Disposable.Create(() => isCancelled = true),
                       innerDisp
                       ));
        }
Ejemplo n.º 25
0
        public void AssignNull()
        {
            int i = 0;
            var d = new SerialDisposable();

            d.Disposable = Disposable.Create(() => i++);
            d.Disposable = null;             // this disposes previous disposable.
            d.Dispose();
            Assert.IsTrue(d.IsDisposed, "#1");
            Assert.AreEqual(1, i, "#2");
        }
Ejemplo n.º 26
0
        public static void DisposesOnAssignWhenDisposed()
        {
            using var serialDisposable = new SerialDisposable <IDisposable>();
#pragma warning disable IDISP016, IDISP017 // Don't use disposed instance.
            serialDisposable.Dispose();
#pragma warning restore IDISP016, IDISP017 // Don't use disposed instance.
            var mock = new Mock <IDisposable>(MockBehavior.Strict);
            mock.Setup(x => x.Dispose());
            serialDisposable.Disposable = mock.Object;
            mock.Verify(x => x.Dispose(), Times.Once);
        }
        public void Serial()
        {
            var d = new SerialDisposable();

            d.IsDisposed.IsFalse();
            var id1 = new IdDisp(1);
            var id2 = new IdDisp(2);
            var id3 = new IdDisp(3);

            // dispose first
            d.Dispose();
            d.IsDisposed.IsTrue();

            d.Disposable = id1; id1.IsDisposed.IsTrue();
            d.Disposable = id2; id2.IsDisposed.IsTrue();
            d.Disposable = id3; id3.IsDisposed.IsTrue();

            // normal flow
            d   = new SerialDisposable();
            id1 = new IdDisp(1);
            id2 = new IdDisp(2);
            id3 = new IdDisp(3);

            d.Disposable = id1; id1.IsDisposed.IsFalse();
            d.Dispose();
            id1.IsDisposed.IsTrue();
            d.Disposable = id2; id2.IsDisposed.IsTrue();
            d.Disposable = id3; id3.IsDisposed.IsTrue();

            // exception flow
            d            = new SerialDisposable();
            id1          = new IdDisp(1);
            id2          = new IdDisp(2);
            id3          = new IdDisp(3);
            d.Disposable = id1;
            id1.IsDisposed.IsFalse();
            d.Disposable = id2;
            id1.IsDisposed.IsTrue();
            id2.IsDisposed.IsFalse();
            d.Disposable = id3;
            id2.IsDisposed.IsTrue();
            id3.IsDisposed.IsFalse();

            d.Dispose();

            id3.IsDisposed.IsTrue();

            // null
            d            = new SerialDisposable();
            id1          = new IdDisp(1);
            d.Disposable = null;
            d.Dispose();
            d.Disposable = null;
        }
Ejemplo n.º 28
0
        public SavegameService(
            SavegamesConfig savegamesConfig,
            IDataStorageStrategy dataStorageStrategy)
        {
            _savegamesConfig     = savegamesConfig;
            _dataStorageStrategy = dataStorageStrategy;

            _savegameDisposer   = new SerialDisposable().AddTo(Disposer);
            _saveDisposer       = new SerialDisposable().AddTo(Disposer);
            _requestSaveTimeout = TimeSpan.FromSeconds(_savegamesConfig.RequestSaveTimeoutSeconds);
        }
Ejemplo n.º 29
0
        public Grid() : base()
        {
            _rowDefinitions    = new RowDefinitionCollection(this);
            _columnDefinitions = new ColumnDefinitionCollection(this);

            _subscriptions       = new SerialDisposable();
            _rowSubscriptions    = new SerialDisposable();
            _columnSubscriptions = new SerialDisposable();

            Children.CollectionChanged += Children_CollectionChanged;
        }
Ejemplo n.º 30
0
 public void DisposesOnAssignWhenDisposed()
 {
     using (var serialDisposable = new SerialDisposable <IDisposable>())
     {
         serialDisposable.Dispose();
         var mock = new Mock <IDisposable>(MockBehavior.Strict);
         mock.Setup(x => x.Dispose());
         serialDisposable.Disposable = mock.Object;
         mock.Verify(x => x.Dispose(), Times.Once);
     }
 }
Ejemplo n.º 31
0
        public void Serial()
        {
            var d = new SerialDisposable();
            d.IsDisposed.IsFalse();
            var id1 = new IdDisp(1);
            var id2 = new IdDisp(2);
            var id3 = new IdDisp(3);

            // dispose first
            d.Dispose();
            d.IsDisposed.IsTrue();

            d.Disposable = id1; id1.IsDisposed.IsTrue();
            d.Disposable = id2; id2.IsDisposed.IsTrue();
            d.Disposable = id3; id3.IsDisposed.IsTrue();

            // normal flow
            d = new SerialDisposable();
            id1 = new IdDisp(1);
            id2 = new IdDisp(2);
            id3 = new IdDisp(3);

            d.Disposable = id1; id1.IsDisposed.IsFalse();
            d.Dispose();
            id1.IsDisposed.IsTrue();
            d.Disposable = id2; id2.IsDisposed.IsTrue();
            d.Disposable = id3; id3.IsDisposed.IsTrue();

            // exception flow
            d = new SerialDisposable();
            id1 = new IdDisp(1);
            id2 = new IdDisp(2);
            id3 = new IdDisp(3);
            d.Disposable = id1;
            id1.IsDisposed.IsFalse();
            d.Disposable = id2;
            id1.IsDisposed.IsTrue();
            id2.IsDisposed.IsFalse();
            d.Disposable = id3;
            id2.IsDisposed.IsTrue();
            id3.IsDisposed.IsFalse();

            d.Dispose();

            id3.IsDisposed.IsTrue();

            // null
            d = new SerialDisposable();
            id1 = new IdDisp(1);
            d.Disposable = null;
            d.Dispose();
            d.Disposable = null;
        }