/// <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); }
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; } }
/// <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); }