Exemple #1
0
        public static void RefCountDisposable_SuppliesAsManyDependentDisposablesAsYouNeed_ButOnlyGetsDisposedAfterAllDependentsAreDisposedOf()
        {
            //Can be used as part of a synchonization mechanism

            var refCountDisposable = new RefCountDisposable(
                Disposable.Create(() =>
                                  Debug.WriteLine("Underlying disposable has been disposed.")));

            var firstDependentDisposable  = refCountDisposable.GetDisposable();
            var secondDependentDisposable = refCountDisposable.GetDisposable();
            var thirdDependentDisposable  = refCountDisposable.GetDisposable();

            Console.WriteLine("Disposing of the second dependent.");
            secondDependentDisposable.Dispose();

            Console.WriteLine("Trying to dispose of the RefCountDisposable");
            refCountDisposable.Dispose();

            Console.WriteLine($"Evidently it fails! RefCountDisposable is disposed: {refCountDisposable.IsDisposed}");

            Console.WriteLine("Disposing of the third dependent.");
            thirdDependentDisposable.Dispose();

            Console.WriteLine("Disposing of the first dependent.");
            firstDependentDisposable.Dispose();

            Console.WriteLine($"Now that the last dependent is disposed, RefCountDisposable is disposed: {refCountDisposable.IsDisposed}");
        }
Exemple #2
0
        public void RefCountDisposable_RefCounting()
        {
            var d = new BooleanDisposable();
            var r = new RefCountDisposable(d);

            Assert.False(d.IsDisposed);

            var d1 = r.GetDisposable();
            var d2 = r.GetDisposable();

            Assert.False(d.IsDisposed);

            d1.Dispose();
            Assert.False(d.IsDisposed);

            d2.Dispose();
            Assert.False(d.IsDisposed); // CHECK

            r.Dispose();
            Assert.True(d.IsDisposed);
            Assert.True(r.IsDisposed);

            var d3 = r.GetDisposable(); // CHECK

            d3.Dispose();
        }
Exemple #3
0
        /// <summary>
        /// RefCountDisposable 可以使用 GetDisposable 来生成新的 Disposable,并且只会在生成的 Disposable 全部调用完 Dispose 之后,才会执行自己的 Dispose
        /// </summary>
        public static void RefCountDisposable()
        {
            var refCount = new RefCountDisposable(Disposable.Create(() => Console.WriteLine("Disposing refCount")));
            var d1       = refCount.GetDisposable();
            var d2       = refCount.GetDisposable();

            refCount.Dispose();
            Console.WriteLine("Disposing 1st");
            d1.Dispose();
            Console.WriteLine("Disposing 2nd");
            d2.Dispose();
        }
Exemple #4
0
        public async void AsyncDisposeTest()
        {
            pipe = new EventPipe();
            var endThing = new TaskCompletionSource <bool>();
            var disposer = new RefCountDisposable(Disposable.Create(() => endThing.SetResult(true)));

            for (var i = 0; i < 100; i++)
            {
                pipe.ObserveFirst.Subscribe(new TestObserver(i, outp, "first", disposer.GetDisposable()));
                pipe.ObserveConcurrent.Subscribe(new TestObserver(i, outp, "reader", disposer.GetDisposable()));
                pipe.ObserveSynchronous.Subscribe(new TestObserver(i, outp, "writer", disposer.GetDisposable()));
            }
            disposer.Dispose();
            //var testTask = new List<Task>();
            var totalDisposer = new RefCountDisposable(Disposable.Create(() => pipe.Complete()));
            var rand          = new Random();

            Parallel.ForEach(Enumerable.Range(0, 99), async x =>
            {
                using (totalDisposer.GetDisposable())
                {
                    using (var scp = testProv.CreateScope())
                    {
                        var e = new MessageEvent
                        {
                            IgnoreThis  = false,
                            Services    = scp.ServiceProvider.CreateScope().ServiceProvider,
                            Scenario    = VersaCommsID.FromEnum(EVersaCommIDType.Scenario, 0),
                            Player      = new UnionType <VersaCommsID, IPlayer>(0),
                            Terminal    = new UnionType <VersaCommsID, IVersaWriter>(0),
                            FullMessage = x.ToString(),
                            Entity      = new UnionType <VersaCommsID, IEntity>(0),
                        };
                        await Task.Yield();
                        await pipe.ProcessEvent(e);
                    }
                }
            });

            //totalDisposer.Dispose();
            //scp.Dispose();
            //await Task.WhenAll(testTask);

            await Task.Delay(200);

            totalDisposer.Dispose();
            //await Task.Delay(200);
            await endThing.Task;
            //pipe.Dispose();
        }
Exemple #5
0
        /// <summary>
        /// Runs or observes a single catchup batch asynchronously for multiple catchup instances.
        /// </summary>
        public static IObservable <ReadModelCatchupStatus> SingleBatchAsync(
            params ReadModelCatchup <ReadModelDbContext>[] catchups)
        {
            return(Observable.Create <ReadModelCatchupStatus>(observer =>
            {
                if (!catchups?.Any() ?? true)
                {
                    observer.OnCompleted();
                    return Disposable.Empty;
                }

                var completions = new RefCountDisposable(Disposable.Create(observer.OnCompleted));

                var subscriptions = new CompositeDisposable();

                catchups.ForEach(catchup =>
                {
                    var completion = completions.GetDisposable();

                    var sub = catchup.SingleBatchAsync()
                              .Subscribe(onNext: observer.OnNext,
                                         onCompleted: completion.Dispose);

                    subscriptions.Add(sub);
                });

                completions.Dispose();

                return subscriptions;
            }));
        }
Exemple #6
0
        public IDisposable Subscribe(ICompletableObserver observer)
        {
            var velocity = GetVelocity(_property).ToReactiveProperty();

            var outerDisposable    = new SingleAssignmentDisposable();
            var currentTween       = new SerialDisposable();
            var observerCompletion = new RefCountDisposable(Disposable.Create(observer.OnCompleted));

            outerDisposable.Disposable = new CompositeDisposable
                                         (
                _target.Subscribe(x =>
            {
                // Prevent observer from completing while there is a tween in progress
                var tweenCompletion = observerCompletion.GetDisposable();

                // Dispose any previous tween in progress, if any
                currentTween.Disposable = new CompositeDisposable
                                          (
                    Tween(_property, x, _duration, velocity.Value, _easer)
                    .SubscribeAndForget(tweenCompletion.Dispose),
                    tweenCompletion
                                          );
            },
                                  () => observerCompletion.Dispose()),
                currentTween
                                         );

            return(outerDisposable);
        }
        public void RefCountDisposable_AsFactory_Test()
        {
            // arrange
            const int COUNT = 10;

            var innerDisposable = new BooleanDisposable();
            var dispFactory     = new RefCountDisposable(innerDisposable);

            // act
            var dispodables = from i in Enumerable.Range(0, COUNT)
                              // will produce a related disposable
                              select dispFactory.GetDisposable();

            dispodables = dispodables.ToArray();

            dispFactory.Dispose(); // Start with single reference

            // verify
            foreach (IDisposable d in dispodables)
            {
                Assert.IsFalse(innerDisposable.IsDisposed);
                Assert.IsFalse(dispFactory.IsDisposed);
                d.Dispose();
            }

            Assert.IsTrue(dispFactory.IsDisposed);
            Assert.IsTrue(innerDisposable.IsDisposed);
        }
Exemple #8
0
        public static ISequence <ISequence <T> > Window <T>(this ISequence <T> source, int windowSize, int queueLimit = 1)
        {
            if (queueLimit < 1)
            {
                throw new ArgumentOutOfRangeException("queueLimit must be greater that one.");
            }

            return(Create <ISequence <T> >(context =>
            {
                Task <bool> lastCopyToResult = null;
                var i = source.Start(context);
                var subscription = new RefCountDisposable(i);
                return Iterator.Create <ISequence <T> >(async(r, c) =>
                {
                    if (lastCopyToResult != null && await lastCopyToResult.ConfigureAwait(false) == false)
                    {
                        return false;
                    }

                    if (!await i.MoveNext(c).ConfigureAwait(false))
                    {
                        return false;
                    }

                    var queue = new AsyncQueue <T>(queueLimit);
                    await queue.OnNext(i.Current, c).ConfigureAwait(false);

                    r.Value = Create(context2 => new AnonymousIterator <T>(queue.MoveNext, () => queue.Current, queue.Dispose, Enumerable.Empty <Task>, context2));
                    var keepAlive = subscription.GetDisposable();
                    lastCopyToResult = CopyToQueue(i, queue, windowSize - 1, CancellationToken.None, true).Finally(keepAlive.Dispose);
                    return true;
                }, context, subscription);
            }));
        }
        public IDisposable Subscribe(IObserver <TElement> observer)
        {
            var release      = refCount.GetDisposable();
            var subscription = subject.Subscribe(observer);

            return(StableCompositeDisposable.Create(release, subscription));
        }
Exemple #10
0
        public IDisposable Subscribe(UniRx.IObserver <TElement> observer)
        {
            IDisposable disposable  = refCount.GetDisposable();
            IDisposable disposable2 = subject.Subscribe(observer);

            return(StableCompositeDisposable.Create(disposable, disposable2));
        }
Exemple #11
0
 static IObservable <T> AddRef <T>(IObservable <T> xs, RefCountDisposable r)
 {
     return(Observable.Create <T>((IObserver <T> observer) => new CompositeDisposable(new IDisposable[]
     {
         r.GetDisposable(),
         xs.Subscribe(observer)
     })));
 }
        public void GetDisposableDisposeFirst()
        {
            int i   = 0;
            var src = Disposable.Create(() => i++);
            var d   = new RefCountDisposable(src);
            var des = d.GetDisposable();

            Assert.AreNotSame(src, des, "#1");
            d.Dispose();              // triggers final disposable, up to refcount.
            Assert.AreEqual(0, i, "#2");
            des.Dispose();
            Assert.AreEqual(1, i, "#3");
            Assert.IsTrue(d.IsDisposed);

            des = d.GetDisposable();
            des.Dispose();
            Assert.AreEqual(1, i, "#4");
        }
Exemple #13
0
        private static void RefCountDisposable()
        {
            Demo.DisplayHeader("The RefCountDisposable - dispose the underlying disposable when all referencing disposables are dispsosed");

            var inner = Disposable.Create(() => Console.WriteLine("Disposing inner-disposable"));
            var refCountDisposable = new RefCountDisposable(inner);
            var d1 = refCountDisposable.GetDisposable();
            var d2 = refCountDisposable.GetDisposable();
            var d3 = refCountDisposable.GetDisposable();

            refCountDisposable.Dispose();
            Console.WriteLine("Disposing 1st");
            d1.Dispose();
            Console.WriteLine("Disposing 2nd");
            d2.Dispose();
            Console.WriteLine("Disposing 3rd");
            d3.Dispose();
        }
Exemple #14
0
        public void Open()
        {
            if (String.IsNullOrEmpty(connectionName))
            {
                return;
            }

            lock (sync) {
                //если две нитки используют один RasHelper и одна уже получила ссылку
                if (connectionRef != Disposable.Empty)
                {
                    return;
                }
                //если соединение есть и его открыли мы тогда берем ссылку
                if (connection != null && !connection.IsDisposed)
                {
                    connectionRef = connection.GetDisposable();
                    return;
                }

                //если соединение открыли не мы, тогда выходим
                if (RasConnection.GetActiveConnections().Any(c => c.EntryName == connectionName))
                {
                    return;
                }

                string phonebookPath = null;
                foreach (var path in GetPhoneBooks())
                {
                    using (var book = new RasPhoneBook()) {
                        book.Open(path);
                        if (book.Entries.Any(e => e.Name.Match(connectionName)))
                        {
                            phonebookPath = book.Path;
                        }
                    }
                }

                if (phonebookPath == null)
                {
                    log.Warn($"Не удалось найти соединение {connectionName}, удаленное соединение устанавливаться не будет");
                    return;
                }

                using (var dialer = new RasDialer()) {
                    dialer.PhoneBookPath = phonebookPath;
                    dialer.EntryName     = connectionName;
                    var handle = dialer.Dial();

                    var rasConnection = RasConnection.GetActiveConnections().FirstOrDefault(c => c.Handle == handle);
                    connection    = new RefCountDisposable(Disposable.Create(() => rasConnection?.HangUp()));
                    connectionRef = connection.GetDisposable();
                    connection.Dispose();
                }
            }
        }
        public void GetDisposableDisposeLater()
        {
            int i   = 0;
            var src = Disposable.Create(() => i++);
            var d   = new RefCountDisposable(src);
            var des = d.GetDisposable();

            Assert.AreNotSame(src, des, "#1");
            Assert.AreEqual(0, i, "#2");
            des.Dispose();
            Assert.AreEqual(0, i, "#3");
            Assert.IsFalse(d.IsDisposed);

            des = d.GetDisposable();
            des.Dispose();
            Assert.AreEqual(0, i, "#4");
            d.Dispose();              // finally, it calls src dispose
            Assert.AreEqual(1, i, "#5");
        }
Exemple #16
0
        public void RefCountDisposable_Throw_If_Disposed()
        {
            var d = new BooleanDisposable();
            var r = new RefCountDisposable(d, true);

            r.Dispose();

            Assert.True(d.IsDisposed);

            ReactiveAssert.Throws <ObjectDisposedException>(() => { r.GetDisposable(); });
        }
Exemple #17
0
        public void RefCountDisposable_PrimaryDisposesFirst()
        {
            var d = new BooleanDisposable();
            var r = new RefCountDisposable(d);

            Assert.False(d.IsDisposed);

            var d1 = r.GetDisposable();
            var d2 = r.GetDisposable();

            Assert.False(d.IsDisposed);

            d1.Dispose();
            Assert.False(d.IsDisposed);

            r.Dispose();
            Assert.False(d.IsDisposed);

            d2.Dispose();
            Assert.True(d.IsDisposed);
        }
        public static IDisposable Subscribe(Func <ObservableConsole, IDisposable> subscribe)
        {
            lock (_systemConsoleSwapLock)
            {
                if (_refCount is null || _refCount.IsDisposed)
                {
                    var console = new ConsoleOutput
                    {
                        _originalOutputWriter = Console.Out,
                        _originalErrorWriter  = Console.Error
                    };

                    _out   = new MultiplexingTextWriter();
                    _error = new MultiplexingTextWriter();

                    Console.SetOut(_out);
                    Console.SetError(_error);

                    _refCount = new RefCountDisposable(Disposable.Create(() =>
                    {
                        _out      = null;
                        _error    = null;
                        _refCount = null;

                        console.RestoreSystemConsole();
                    }));
                }

                var writerForCurrentContext = EnsureInitializedForCurrentAsyncContext();

                var observableConsole = new ObservableConsole(
                    @out: _out.GetObservable(),
                    error: _error.GetObservable());

                return(new CompositeDisposable
                {
                    _refCount,
                    _refCount.GetDisposable(),
                    subscribe(observableConsole),
                    writerForCurrentContext
                });

                IDisposable EnsureInitializedForCurrentAsyncContext() =>
                new CompositeDisposable
                {
                    _out.EnsureInitializedForCurrentAsyncContext(),
                        _error.EnsureInitializedForCurrentAsyncContext()
                };
            }
        }
        protected override IDisposable SubscribeCore(IObserver <TElement> observer)
        {
            if (_refCount != null)
            {
                //
                // [OK] Use of unsafe Subscribe: called on a known subject implementation.
                //
                var release      = _refCount.GetDisposable();
                var subscription = _subject.Subscribe/*Unsafe*/ (observer);
                return(StableCompositeDisposable.Create(release, subscription));
            }

            //
            // [OK] Use of unsafe Subscribe: called on a known subject implementation.
            //
            return(_subject.Subscribe/*Unsafe*/ (observer));
        }
            public async ValueTask <LockHolder> GetLockAsync(CancellationToken cancellationToken)
            {
                var refCount = refCountDisposable.GetDisposable();

                if (refCountDisposable.IsDisposed)
                {
                    return(new LockHolder(false, refCount, null));
                }
                else
                {
                    try
                    {
                        await semaphoreSlim.WaitAsync(cancellationToken).ConfigureAwait(false);
                    }
                    catch
                    {
                        refCount.Dispose();
                        throw;
                    }
                    return(new LockHolder(true, refCount, semaphoreSlim));
                }
            }
 public GroupedObservable(TKey key, IObservable <TElement> underlyingObservable, RefCountDisposable mergedDisposable)
 {
     this.Key = key;
     this.underlyingObservable = new AnonymousObservable <TElement>(observer =>
                                                                    new CompositeDisposable(mergedDisposable.GetDisposable(), underlyingObservable.Subscribe(observer)));
 }
 public RepositoryWrapper(string path)
 {
     _repository         = new LibGit2Sharp.Repository(path);
     _refCountDisposable = new RefCountDisposable(_repository);
     _disposable         = _refCountDisposable.GetDisposable();
 }
 public IDisposable AddRef()
 => _refCountDisposable.GetDisposable();
Exemple #24
0
        private static void Impl(bool primaryFirst, bool primaryRandom, IEnumerable <int> nDependents)
        {
            var rand = new Random();

            foreach (var n in nDependents)
            {
                var e            = new ManualResetEvent(false);
                var hasDependent = new ManualResetEvent(false);
                var r            = new RefCountDisposable(Disposable.Create(() => { e.Set(); }));

                var d = default(IDisposable);
                if (primaryFirst)
                {
                    d = r.GetDisposable();
                    r.Dispose();
                }
                else if (primaryRandom)
                {
                    var sleep = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0;

                    ThreadPool.QueueUserWorkItem(_ =>
                    {
                        hasDependent.WaitOne();
                        Helpers.SleepOrSpin(sleep);
                        r.Dispose();
                    });

                    if (n == 0)
                    {
                        hasDependent.Set();
                    }
                }

                Console.Write(n + " - ");

                var cd = new CountdownEvent(n * 2);
                for (int i = 0; i < n; i++)
                {
                    var j = i;

                    var sleep1 = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0;
                    var sleep2 = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0;
                    var sleep3 = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0;

                    ThreadPool.QueueUserWorkItem(_ =>
                    {
                        Helpers.SleepOrSpin(sleep1);

                        Console.Write("+");

                        var f = r.GetDisposable();

                        if (j == 0)
                        {
                            hasDependent.Set();
                        }

                        Helpers.SleepOrSpin(sleep2);

                        ThreadPool.QueueUserWorkItem(__ =>
                        {
                            Helpers.SleepOrSpin(sleep3);

                            f.Dispose();

                            Console.Write("-");

                            cd.Signal();
                        });

                        cd.Signal();
                    });
                }

                cd.Wait();

                if (primaryFirst)
                {
                    d.Dispose();
                }
                else if (!primaryRandom)
                {
                    r.Dispose();
                }

                e.WaitOne();

                Console.WriteLine(".");
            }
        }