public void AccessingAfterDisposingTest() { var instance = new TestShareableDisposable(); var resourceHolder = instance.GetResourceHolder(); Assert.IsFalse(resourceHolder.IsResourceReleased, "Resource should not be released."); instance.Dispose(); Assert.IsTrue(resourceHolder.IsResourceReleased, "Resource should be released."); try { instance.GetResourceHolder(); throw new AssertionException("Instance should not be accessible after disposing."); } catch (AssertionException) { throw; } catch { } try { instance.Share(); throw new AssertionException("Instance should not be shared after disposing."); } catch (AssertionException) { throw; } catch { } }
public void SharingOnSingleThreadTest() { // build base instance var baseInstance = new TestShareableDisposable(); var resourceHolder = baseInstance.GetResourceHolder(); Assert.IsFalse(resourceHolder.IsResourceReleased, "Resource should not be released."); // share var sharedInstance = baseInstance.Share(); Assert.AreNotSame(baseInstance, sharedInstance, "Shared instance should not be same as base instance."); Assert.AreSame(resourceHolder, sharedInstance.GetResourceHolder(), "Resource holder of shared instance should be same as base instance."); // dispose shared instance sharedInstance.Dispose(); Assert.IsFalse(resourceHolder.IsResourceReleased, "Resource should not be released after disposing shared instance."); // share and dispose base instance sharedInstance = baseInstance.Share(); baseInstance.Dispose(); Assert.IsFalse(resourceHolder.IsResourceReleased, "Resource should not be released before disposing all instances."); // dispose shared instance sharedInstance.Dispose(); Assert.IsTrue(resourceHolder.IsResourceReleased, "Resource should be released after disposing all instances."); }
public void SharingOnMultiThreadsTest() { // build base instance var baseInstance = new TestShareableDisposable(); var resourceHolder = baseInstance.GetResourceHolder(); Assert.IsFalse(resourceHolder.IsResourceReleased, "Resource should not be released."); // share instance on multiple threads var syncLock = new object(); var completedCount = 0; var exception = (Exception?)null; lock (syncLock) { for (int i = 0; i < 100; ++i) { ThreadPool.QueueUserWorkItem((_) => { try { using (var sharedInstance = baseInstance.Share()) { Assert.IsFalse(resourceHolder.IsResourceReleased, "Resource should not be released after sharing instance."); Thread.Sleep(this.random.Next(10, 100)); } } catch (Exception ex) { exception = ex; } finally { lock (syncLock) { ++completedCount; if (completedCount == 100 || exception != null) { Monitor.Pulse(syncLock); } } } }); } Assert.IsTrue(Monitor.Wait(syncLock, 10000), "Cannot complete waiting for sharing instance on multi-threads."); } if (exception != null) { throw exception; } // dispose base instance Assert.IsFalse(resourceHolder.IsResourceReleased, "Resource should not be released before disposing all instances."); baseInstance.Dispose(); Assert.IsTrue(resourceHolder.IsResourceReleased, "Resource should be released after disposing all instances."); }