public static void Main(string[] args) { { #region Snippet_10a IDisposable disposable = new ReaderWriterLockSlim(); IDisposeList disposeList = new DisposeList(); disposeList.AddDisposable(disposable); // ... do work ... and dispose both. disposeList.Dispose(); #endregion Snippet_10a } { #region Snippet_10b IDisposeList disposeList = new DisposeList(); disposeList.AddDisposeAction(_ => Console.WriteLine("Disposed"), null); // ... do work ... disposeList.Dispose(); #endregion Snippet_10b } { #region Snippet_10c IBelatableDispose disposeList = new DisposeList(); // Postpone dispose IDisposable belateDisposeHandle = disposeList.BelateDispose(); // Start concurrent work Task.Run(() => { // Do work Thread.Sleep(100); // Release belate handle. Disposes here or below, depending which thread runs last. belateDisposeHandle.Dispose(); }); // Start dispose, but postpone it until belatehandle is disposed in another thread. disposeList.Dispose(); #endregion Snippet_10c } }
public void TestBelateNonDispose() { Semaphore s = new Semaphore(0, 100); // Create object DisposeList disp = FileSystem.OS; // Belate dispose, this handle is passed to the task IDisposable belateHandle = disp.BelateDispose(); // Start work Task.Run(() => { // Do work Thread.Sleep(1000); // Assert.IsFalse(disp.IsDisposing); Assert.IsTrue(disp.IsDisposeCalled); // Release belate handle belateHandle.Dispose(); // Check is disposed Assert.IsFalse(disp.IsDisposed); // s.Release(); }); // Start dispose, which is postponed disp.Dispose(); // Check is disposed Assert.IsTrue(disp.IsDisposeCalled); Assert.IsFalse(disp.IsDisposed); Assert.IsFalse(disp.IsDisposing); // The test exists before the thread s.WaitOne(); Assert.IsFalse(disp.IsDisposeCalled); Assert.IsFalse(disp.IsDisposing); Assert.IsFalse(disp.IsDisposed); }