public void TestKeepAliveMax()
        {
            WeakReference r;
            ObjectKeepAlive keep = new ObjectKeepAlive(25, 50, TimeSpan.FromSeconds(1));

            if(true)
            {
                object target = new MyObject();
                r = new WeakReference(target);
                keep.Add(target);
                target = null;
            }

            _destroyed = false;
            Assert.IsTrue(r.IsAlive);

            for (int i = 0; i < 49; i++)
                keep.Add(i);

            Assert.IsTrue(r.IsAlive);

            GC.GetTotalMemory(true);
            GC.WaitForPendingFinalizers();
            Assert.IsTrue(r.IsAlive);
            Assert.IsFalse(_destroyed);

            keep.Add(new object());
            keep.Add(new object());

            GC.GetTotalMemory(true);
            GC.WaitForPendingFinalizers();
            Assert.IsFalse(r.IsAlive);
            Assert.IsTrue(_destroyed);
        }
        public void TestKeepAliveMin()
        {
            WeakReference r;
            ObjectKeepAlive keep = new ObjectKeepAlive(1, 10, TimeSpan.FromTicks(1), true);

            for (int i = 0; i < 35; i++)
                keep.Add(i);

            if (true)
            {
                object target = new MyObject();
                r = new WeakReference(target);
                keep.Add(target);
                target = null;
            }

            _destroyed = false;
            Assert.IsTrue(r.IsAlive);

            for (int i = 0; i < 100; i++)
                keep.Tick();

            Assert.IsTrue(r.IsAlive);

            GC.GetTotalMemory(true);
            GC.WaitForPendingFinalizers();
            Assert.IsTrue(r.IsAlive);
            Assert.IsFalse(_destroyed);

            System.Threading.Thread.Sleep(1);

            GC.GetTotalMemory(true);
            GC.WaitForPendingFinalizers();
            Assert.IsTrue(r.IsAlive);
            Assert.IsFalse(_destroyed);

            keep.Clear();

            GC.GetTotalMemory(true);
            GC.WaitForPendingFinalizers();
            Assert.IsFalse(r.IsAlive);
            Assert.IsTrue(_destroyed);
        }
        public void TestTruncateLarge()
        {
            TimeSpan timeout = TimeSpan.FromMilliseconds(25);
            ObjectKeepAlive keep = new ObjectKeepAlive(100, 10000, timeout);

            for (int i = 0; i < 100000; i++)
                keep.Add(i);

            System.Threading.Thread.Sleep(timeout);

            for (int i = 0; i < 10000; i++)
                keep.Add(i);
        }
        public void TestKeepAliveTime()
        {
            WeakReference r;
            TimeSpan timeout = TimeSpan.FromMilliseconds(100);
            ObjectKeepAlive keep = new ObjectKeepAlive(1, 10, timeout, false);

            if (true)
            {
                object target = new MyObject();
                r = new WeakReference(target);
                keep.Add(target);
                target = null;
            }

            _destroyed = false;
            Assert.IsTrue(r.IsAlive);

            for (int i = 0; i < 5; i++)
                keep.Add(i);

            Assert.IsTrue(r.IsAlive);

            GC.GetTotalMemory(true);
            GC.WaitForPendingFinalizers();
            Assert.IsTrue(r.IsAlive);
            Assert.IsFalse(_destroyed);

            long start = DateTime.UtcNow.Ticks;
            while ((start + timeout.Ticks) > DateTime.UtcNow.Ticks)
                System.Threading.Thread.SpinWait(100);

            //Time has elapsed, yet it nothing is added, and Tick() is not called, it remains in memory
            GC.GetTotalMemory(true);
            GC.WaitForPendingFinalizers();
            Assert.IsTrue(r.IsAlive);
            Assert.IsFalse(_destroyed);

            //Once the collection is touched with either a call to Add or Tick, timeout will expire
            keep.Add(new object());

            GC.GetTotalMemory(true);
            GC.WaitForPendingFinalizers();
            Assert.IsFalse(r.IsAlive);
            Assert.IsTrue(_destroyed);
        }