Ejemplo n.º 1
0
            public IDisposable Run()
            {
                _totalTime = TimeSpan.Zero;
                _nextShift = _parent._timeShift;
                _nextSpan  = _parent._timeSpan;

                _gate = new object();
                _q    = new Queue <ISubject <TSource> >();

                _timerD = new SerialDisposable();

                var groupDisposable = new CompositeDisposable(2)
                {
                    _timerD
                };

                _refCountDisposable = new RefCountDisposable(groupDisposable);

                CreateWindow();
                CreateTimer();

                groupDisposable.Add(_parent._source.SubscribeSafe(this));

                return(_refCountDisposable);
            }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
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);
            }));
        }
Ejemplo n.º 5
0
        public static ONIDisposable ReserveDAQ(uint context_index = 0)
        {
            Tuple <ONIController, RefCountDisposable> oni_context;

            lock (openContextsLock)
            {
                if (!openContexts.TryGetValue(context_index, out oni_context)) // Context has not been opened yet
                {
                    ONIController oni;                                         // Does not call constructor
                    var           configuration = LoadConfiguration();
                    if (configuration.Contains(context_index))                 // There is a configuration file specifying non-default channel paths
                    {
                        var config = configuration[context_index];             // Nothing used yet
                        oni = new ONIController(config.ConfigurationPath, config.DataInputPath, config.SignalPath);
                    }
                    else
                    {
                        oni = new ONIController(); // Default params
                    }

                    var dispose = Disposable.Create(() =>
                    {
                        //oni.DAQ.Dispose(false);
                        openContexts.Remove(context_index);
                    });

                    var ref_count = new RefCountDisposable(dispose);
                    oni_context = Tuple.Create(oni, ref_count);
                    openContexts.Add(context_index, oni_context);
                    return(new ONIDisposable(oni, ref_count));
                }
            }

            return(new ONIDisposable(oni_context.Item1, oni_context.Item2.GetDisposable())); // New reference
        }
Ejemplo n.º 6
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();
        }
Ejemplo n.º 7
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;
            }));
        }
Ejemplo n.º 8
0
 public IDisposable Run()
 {
     groupDisposable    = new CompositeDisposable();
     refCountDisposable = new RefCountDisposable(groupDisposable);
     groupDisposable.Add(parent.source.Subscribe(this));
     return(refCountDisposable);
 }
Ejemplo n.º 9
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}");
        }
        public IObservable <IParseResult <IObservable <TResult> > > Parse(IObservableCursor <TSource> source)
        {
            return(Observable.Defer(() =>
            {
                firstParser = null;

                bool first = true;
                var any = new AnyObservableParser <TSource, TResult>(parsers);
                var except = new List <IObservableParser <TSource, TResult> >();

                // See the AllObservableParser.Parse method for an explanation of the optimization that is provided by SelectMany's TContext argument
                var root = source.Branch();
                var rootDisposable = new RefCountDisposable(root);

                return ObservableParseResult.ReturnSuccessMany <TResult>(0)
                .SelectMany(
                    Tuple.Create(root, rootDisposable),
                    parsers.Select(
                        parser => (Func <Tuple <IObservableCursor <TSource>, RefCountDisposable>, Tuple <IParseResult <IObservable <TResult> >, bool>, Tuple <Tuple <IObservableCursor <TSource>, RefCountDisposable>, IObservable <IParseResult <IObservable <TResult> > > > >)
                            ((context, value) =>
                {
                    if (first)
                    {
                        first = false;
                        firstParser = parser;
                    }

                    var branch = context.Item1;
                    var disposable = context.Item2;
                    var refDisposable = disposable.GetDisposable();

                    IObservable <IParseResult <IObservable <TResult> > > results;

                    // Item2 is only true when value.Item1 is the last element of its sequence.
                    if (value.Item2)
                    {
                        branch.Move(value.Item1.Length);

                        results = any.Parse(except, branch)
                                  .Select(result => result.YieldMany())
                                  .Finally(refDisposable.Dispose);
                    }
                    else
                    {
                        branch = branch.Remainder(value.Item1.Length);

                        disposable = new RefCountDisposable(new CompositeDisposable(branch, refDisposable));

                        results = any.Parse(except, branch)
                                  .Select(result => result.YieldMany())
                                  .Finally(disposable.Dispose);
                    }

                    return Tuple.Create(Tuple.Create(branch, disposable), results);
                })),
                    (firstResult, otherResults) => firstResult.Concat(otherResults))
                .Finally(rootDisposable.Dispose);
            }));
        }
Ejemplo n.º 11
0
            public IDisposable Run(IObservable <TSource> source)
            {
                var sourceSubscription = new SingleAssignmentDisposable();

                _refCountDisposable           = new RefCountDisposable(sourceSubscription);
                sourceSubscription.Disposable = source.SubscribeSafe(this);
                return(_refCountDisposable);
            }
Ejemplo n.º 12
0
                public _(Count parent, IObserver <IObservable <TSource> > observer)
                    : base(observer)
                {
                    _refCountDisposable = new RefCountDisposable(_m);

                    _count = parent._count;
                    _skip  = parent._skip;
                }
Ejemplo n.º 13
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)
     })));
 }
Ejemplo n.º 14
0
            public override void Run(IObservable <TSource> source)
            {
                var sourceSubscription = new SingleAssignmentDisposable();

                _refCountDisposable           = new RefCountDisposable(sourceSubscription);
                sourceSubscription.Disposable = source.SubscribeSafe(this);

                SetUpstream(_refCountDisposable);
            }
Ejemplo n.º 15
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();
                }
            }
        }
Ejemplo n.º 16
0
            public _(GroupByUntil <TSource, TKey, TElement, TDuration> parent, IObserver <IGroupedObservable <TKey, TElement> > observer)
                : base(observer)
            {
                _refCountDisposable = new RefCountDisposable(_groupDisposable);
                _map = new Map <TKey, ISubject <TElement> >(parent._capacity, parent._comparer);

                _keySelector      = parent._keySelector;
                _elementSelector  = parent._elementSelector;
                _durationSelector = parent._durationSelector;
            }
Ejemplo n.º 17
0
        public void RefCountDisposable_SingleReference()
        {
            var d = new BooleanDisposable();
            var r = new RefCountDisposable(d);

            Assert.False(d.IsDisposed);
            r.Dispose();
            Assert.True(d.IsDisposed);
            r.Dispose();
            Assert.True(d.IsDisposed);
        }
Ejemplo n.º 18
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(); });
        }
Ejemplo n.º 19
0
        internal static ArduinoDisposable ReserveConnection(string portName, ArduinoConfiguration arduinoConfiguration)
        {
            var connection = default(Tuple <Arduino, RefCountDisposable>);

            lock (openConnectionsLock)
            {
                if (string.IsNullOrEmpty(portName))
                {
                    if (!string.IsNullOrEmpty(arduinoConfiguration.PortName))
                    {
                        portName = arduinoConfiguration.PortName;
                    }
                    else if (openConnections.Count == 1)
                    {
                        connection = openConnections.Values.Single();
                    }
                    else
                    {
                        throw new ArgumentException("An alias or serial port name must be specified.", "portName");
                    }
                }

                if (connection == null && !openConnections.TryGetValue(portName, out connection))
                {
                    var serialPortName = arduinoConfiguration.PortName;
                    if (string.IsNullOrEmpty(serialPortName))
                    {
                        serialPortName = portName;
                    }

                    var configuration = LoadConfiguration();
                    if (configuration.Contains(serialPortName))
                    {
                        arduinoConfiguration = configuration[serialPortName];
                    }

                    var arduino = new Arduino(serialPortName, arduinoConfiguration.BaudRate);
                    arduino.Open();
                    arduino.SamplingInterval(arduinoConfiguration.SamplingInterval);
                    var dispose = Disposable.Create(() =>
                    {
                        arduino.Close();
                        openConnections.Remove(portName);
                    });

                    var refCount = new RefCountDisposable(dispose);
                    connection = Tuple.Create(arduino, refCount);
                    openConnections.Add(portName, connection);
                    return(new ArduinoDisposable(arduino, refCount));
                }
            }

            return(new ArduinoDisposable(connection.Item1, connection.Item2.GetDisposable()));
        }
Ejemplo n.º 20
0
            public _(GroupJoin <TLeft, TRight, TLeftDuration, TRightDuration, TResult> parent, IObserver <TResult> observer, IDisposable cancel)
                : base(observer, cancel)
            {
                _refCount = new RefCountDisposable(_group);
                _leftMap  = new SortedDictionary <int, IObserver <TRight> >();
                _rightMap = new SortedDictionary <int, TRight>();

                _leftDurationSelector  = parent._leftDurationSelector;
                _rightDurationSelector = parent._rightDurationSelector;
                _resultSelector        = parent._resultSelector;
            }
Ejemplo n.º 21
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();
        }
Ejemplo n.º 22
0
        protected override IDisposable Run(IObserver <IGroupedObservable <TKey, TElement> > observer, IDisposable cancel, Action <IDisposable> setSink)
        {
            _groupDisposable    = new CompositeDisposable();
            _refCountDisposable = new RefCountDisposable(_groupDisposable);

            var sink = new _(this, observer, cancel);

            setSink(sink);
            _groupDisposable.Add(_source.SubscribeSafe(sink));

            return(_refCountDisposable);
        }
Ejemplo n.º 23
0
                public void Run(TimeHopping parent)
                {
                    var groupDisposable = new CompositeDisposable(2);

                    _refCountDisposable = new RefCountDisposable(groupDisposable);

                    CreateWindow();

                    groupDisposable.Add(parent._scheduler.SchedulePeriodic(parent._timeSpan, Tick));
                    groupDisposable.Add(parent._source.SubscribeSafe(this));

                    SetUpstream(_refCountDisposable);
                }
Ejemplo n.º 24
0
        internal static AudioContextDisposable ReserveContext(string deviceName, int sampleRate, int refresh)
        {
            if (string.IsNullOrEmpty(deviceName))
            {
                var currentContext = OpenTK.Audio.AudioContext.CurrentContext;
                if (currentContext != null)
                {
                    deviceName = currentContext.CurrentDevice;
                }
                else
                {
                    deviceName = OpenTK.Audio.AudioContext.DefaultDevice;
                }
            }

            Tuple <AudioContext, RefCountDisposable> activeContext;

            lock (activeContextLock)
            {
                if (!activeContexts.TryGetValue(deviceName, out activeContext))
                {
                    AudioContext context;
                    var          configuration = LoadConfiguration();
                    if (configuration.Contains(deviceName))
                    {
                        var contextConfiguration = configuration[deviceName];
                        context = new AudioContext(
                            deviceName,
                            contextConfiguration.SampleRate,
                            contextConfiguration.Refresh);
                    }
                    else
                    {
                        context = new AudioContext(deviceName, sampleRate, refresh);
                    }

                    var dispose = Disposable.Create(() =>
                    {
                        context.Dispose();
                        activeContexts.Remove(deviceName);
                    });

                    var refCount = new RefCountDisposable(dispose);
                    activeContext = Tuple.Create(context, refCount);
                    activeContexts.Add(deviceName, activeContext);
                    return(new AudioContextDisposable(context, refCount));
                }
            }

            return(new AudioContextDisposable(activeContext.Item1, activeContext.Item2.GetDisposable()));
        }
Ejemplo n.º 25
0
        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()
                };
            }
        }
Ejemplo n.º 26
0
            public void Dispose()
            {
                RefCountDisposable parent;

                lock (parentLock)
                {
                    parent  = _parent;
                    _parent = null;
                }
                if (parent != null)
                {
                    parent.Release();
                }
            }
Ejemplo n.º 27
0
            public IDisposable Run()
            {
                _buffer = new List <TSource>();
                _gate   = new object();

                var d = new CompositeDisposable(2);

                _refCountDisposable = new RefCountDisposable(d);

                d.Add(_parent._source.SubscribeSafe(this));
                d.Add(_parent._bufferBoundaries.SubscribeSafe(new Omega(this)));

                return(_refCountDisposable);
            }
Ejemplo n.º 28
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();
        }
Ejemplo n.º 29
0
            public IDisposable Run()
            {
                _queue = new Queue <ISubject <TSource> >();
                _n     = 0;
                _m     = new SingleAssignmentDisposable();
                _refCountDisposable = new RefCountDisposable(_m);

                var firstWindow = CreateWindow();

                base._observer.OnNext(firstWindow);

                _m.Disposable = _parent._source.SubscribeSafe(this);

                return(_refCountDisposable);
            }
Ejemplo n.º 30
0
        private ObservableDictionary()
        {
            _state              = new Dictionary <TKey, TValue>();
            _subject            = new Subject <DictionaryNotification <TKey, TValue> >();
            _sourceSubscription = new SingleAssignmentDisposable();
            _refCountDisposable = new RefCountDisposable(_sourceSubscription);
            _disposables        = new CompositeDisposable(_sourceSubscription, _refCountDisposable, _subject);
            _observer           = new Observer(this);

            var connectableObservable =
                _subject.Only(DictionaryNotificationType.Initialised).Select(_ => Unit.Default).Take(1).PublishLast();

            _streamInitialisation = connectableObservable;
            _disposables.Add(connectableObservable.Connect());
        }
Ejemplo n.º 31
0
 public InnerDisposable(RefCountDisposable parent)
 {
     _parent = parent;
 }