public void VerifyCallbackWrappersCollectsUnusedWrappers()
        {
            DateTime endTime = DateTime.Now + TimeSpan.FromSeconds(19);

            var callbackWrappers = new CallbackWrappers();

            RunFullGarbageCollection();
            long memoryAtStart = GC.GetTotalMemory(true);

            while (DateTime.Now < endTime)
            {
                for (int i = 0; i < 128; ++i)
                {
                    CreateCallbackWrapper(callbackWrappers);
                }

                RunFullGarbageCollection();
                callbackWrappers.Collect();
                RunFullGarbageCollection();
            }

            RunFullGarbageCollection();
            long memoryAtEnd = GC.GetTotalMemory(true);

            GC.KeepAlive(callbackWrappers);

            long memory = memoryAtEnd - memoryAtStart;

            Console.WriteLine("{0:N0} bytes used", memory);
            Assert.IsTrue(memory < 1024 * 1024, "Test used too much memory. JetCallbackWrapper objects weren't collected.");
        }
        public void VerifyWrapperIsCollectedWhenCallbackIsCollected()
        {
            JET_CALLBACK callback    = CreateCallback();
            var          callbackRef = new WeakReference(callback);

            var callbackWrappers = new CallbackWrappers();
            var wrapperRef       = new WeakReference(callbackWrappers.Add(callback));

            callback = null;

            RunFullGarbageCollection();
            callbackWrappers.Collect();
            RunFullGarbageCollection();

            // In DEBUG test code, the objects remain alive for an indeterminate amount of time, for some reason.
            // Note that they do get collected if a RETAIL test code is used, even if the product code is DEBUG
            // so it must be something to do with assigning the local variable 'callback' to null and the effect that
            // it has on garbage collecting weak references to it.
#if !DEBUG
            Assert.IsFalse(callbackRef.IsAlive);
            Assert.IsFalse(wrapperRef.IsAlive);
#endif

            // Avoid premature collection of these objects
            GC.KeepAlive(callbackWrappers);
        }
        public void VerifyWrapperIsAliveWhenCallbackIsAlive()
        {
            JET_CALLBACK callback = CreateCallback();

            var callbackWrappers = new CallbackWrappers();
            var wrapperRef       = new WeakReference(callbackWrappers.Add(callback));

            RunFullGarbageCollection();
            callbackWrappers.Collect();
            RunFullGarbageCollection();

            Assert.IsTrue(wrapperRef.IsAlive);

            // Avoid premature collection of these objects
            GC.KeepAlive(callback);
            GC.KeepAlive(callbackWrappers);
        }