Esempio 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
        {
            DisposeEntry entry;

            var current = _entry;

            if (cleanupDelegate == null)
            {
                entry = new DisposeEntry {
                    DisposeItem = disposable, Next = current
                };
            }
            else
            {
                entry = new DisposeEntry
                {
                    DisposeItem     = disposable,
                    CleanupDelegate = () => cleanupDelegate(disposable),
                    Next            = current
                };
            }

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

            SwapWaitAdd(entry);

            return(disposable);
        }
            //protected static Func<DisposeGroupBase, List<DisposeEntry>> _locateDisposeInfos =
            //    m =>
            //    {
            //        if (m._disposeInfoList == null)
            //        {
            //            Interlocked.CompareExchange(ref m._disposeInfoList, new List<DisposeEntry>(), null);

            //        }
            //        return m._disposeInfoList;

            //    };

            /// <summary>
            /// <para>Register logic actions need to be executed when the instance is disposing</para>
            /// <para>注册一个销毁对象时需要执行的操作</para>
            /// </summary>
            /// <param name="newAction">Disposing action/销毁操作</param>
            /// <param name="needCheckInFinalizer">if set to <c>true</c> [need check in finalizer].</param>
            /// <param name="comment">The comment.</param>
            /// <param name="caller">The caller.</param>
            /// <param name="file">The file.</param>
            /// <param name="line">The line.</param>
            public void AddDisposeAction(Action newAction, bool needCheckInFinalizer = false, string comment = "", [CallerMemberName] string caller = "", [CallerFilePath] string file = "", [CallerLineNumber] int line = -1)
            {
                var di = new DisposeEntry
                {
                    CallingCodeContext     = CallingCodeContext.Create(comment, caller, file, line),
                    Action                 = newAction,
                    IsNeedCheckOnFinalizer = needCheckInFinalizer
                };

                _disposeInfoList.Value.Add(di);
            }
Esempio n. 3
0
        private void SwapWaitAdd(DisposeEntry 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;
            }
        }
Esempio n. 4
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 DisposeEntry {
                DisposeItem = disposable, Next = current
            };

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

            SwapWaitAdd(entry);

            return(disposable);
        }