Ejemplo n.º 1
0
        /// <summary>
        /// Add an object for disposal tracking
        /// </summary>
        /// <param name="disposable">disposable object to track</param>
        /// <param name="cleanupDelegate">logic that will be run directly before the object is disposed</param>
        public T AddDisposable <T>(T disposable, Action <T> cleanupDelegate) where T : IDisposable
        {
            DisposableEntry entry;

            if (cleanupDelegate == null)
            {
                entry = new DisposableEntry {
                    DisposableItem = disposable, Next = _entry
                };
            }
            else
            {
                entry = new DisposableEntry
                {
                    DisposableItem = disposable,
                    DisposalAction = () => cleanupDelegate(disposable),
                    Next           = _entry
                };
            }

            var current = _entry;

            if (ReferenceEquals(Interlocked.CompareExchange(ref _entry, entry, current), current))
            {
                return(disposable);
            }

            SwapWaitAdd(entry);

            return(disposable);
        }
Ejemplo n.º 2
0
        private void SwapWaitAdd(DisposableEntry entry)
        {
            var spinWait = new SpinWait();

            spinWait.SpinOnce();

            var current = entry.Next = _entry;

            while (!ReferenceEquals(Interlocked.CompareExchange(ref _entry, entry, current), current))
            {
                spinWait.SpinOnce();

                current = entry.Next = _entry;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Add an object for disposal tracking
        /// </summary>
        /// <param name="disposable">object to track for disposal</param>
        public T AddDisposable <T>(T disposable) where T : IDisposable
        {
            var current = _entry;
            var entry   = new DisposableEntry {
                DisposableItem = disposable, Next = current
            };

            if (ReferenceEquals(Interlocked.CompareExchange(ref _entry, entry, current), current))
            {
                return(disposable);
            }

            SwapWaitAdd(entry);

            return(disposable);
        }