public void NotCollectedIfSubscriberIsNotTheCallbackTarget() { WeakReference wr = null; new Action(() => { var subscriber = new TestSubcriber(); wr = new WeakReference(subscriber); // This creates a closure, so the callback target is not 'subscriber', but an instancce of a compiler generated class // So MC has to keep a strong reference to it, and 'subscriber' won't be collectable MessagingCenter.Subscribe <TestPublisher>(subscriber, "test", p => subscriber.SetSuccess()); })(); GC.Collect(); GC.WaitForPendingFinalizers(); Assert.IsTrue(wr.IsAlive); // The closure in Subscribe should be keeping the subscriber alive Assert.IsNotNull(wr.Target as TestSubcriber); Assert.IsFalse(((TestSubcriber)wr.Target).Successful); var pub = new TestPublisher(); pub.Test(); Assert.IsTrue(((TestSubcriber)wr.Target).Successful); // Since it's still alive, the subscriber should still have received the message and updated the property }
public void SubscriberShouldBeCollected() { new Action(() => { var subscriber = new TestSubcriber(); MessagingCenter.Subscribe <TestPublisher>(subscriber, "test", p => Assert.Fail()); })(); GC.Collect(); GC.WaitForPendingFinalizers(); var pub = new TestPublisher(); pub.Test(); // Assert.Fail() shouldn't be called, because the TestSubcriber object should have ben GCed }
public void StaticCallback() { int i = 4; _subscriber = new TestSubcriber(); // Using a class member so it doesn't get optimized away in Release build MessagingCenter.Subscribe <TestPublisher>(_subscriber, "test", p => MessagingCenterTestsCallbackSource.Increment(ref i)); GC.Collect(); GC.WaitForPendingFinalizers(); var pub = new TestPublisher(); pub.Test(); Assert.IsTrue(i == 5, "The static method should have incremented 'i'"); }
public void StaticCallback() { int i = 4; var subscriber = new TestSubcriber(); MessagingCenter.Subscribe <TestPublisher>(subscriber, "test", p => MessagingCenterTestsCallbackSource.Increment(ref i)); GC.Collect(); GC.WaitForPendingFinalizers(); var pub = new TestPublisher(); pub.Test(); Assert.IsTrue(i == 5, "The static method should have incremented 'i'"); }
public void NothingShouldBeCollected() { var success = false; _subscriber = new TestSubcriber(); // Using a class member so it doesn't get optimized away in Release build var source = new MessagingCenterTestsCallbackSource(); MessagingCenter.Subscribe <TestPublisher>(_subscriber, "test", p => source.SuccessCallback(ref success)); GC.Collect(); GC.WaitForPendingFinalizers(); var pub = new TestPublisher(); pub.Test(); Assert.True(success); // TestCallbackSource.SuccessCallback() should be invoked to make success == true }
public void NothingShouldBeCollected() { var success = false; var subscriber = new TestSubcriber(); var source = new MessagingCenterTestsCallbackSource(); MessagingCenter.Subscribe <TestPublisher>(subscriber, "test", p => source.SuccessCallback(ref success)); GC.Collect(); GC.WaitForPendingFinalizers(); var pub = new TestPublisher(); pub.Test(); Assert.True(success); // TestCallbackSource.SuccessCallback() should be invoked to make success == true }
public void SubscriberCollectableAfterUnsubscribeEvenIfHeldByClosure() { WeakReference wr = null; new Action(() => { var subscriber = new TestSubcriber(); wr = new WeakReference(subscriber); MessagingCenter.Subscribe <TestPublisher>(subscriber, "test", p => subscriber.SetSuccess()); })(); Assert.IsNotNull(wr.Target as TestSubcriber); MessagingCenter.Unsubscribe <TestPublisher>(wr.Target, "test"); GC.Collect(); GC.WaitForPendingFinalizers(); Assert.IsFalse(wr.IsAlive); // The Action target and subscriber were the same object, so both could be collected }
public void ShouldBeCollectedIfCallbackTargetIsSubscriber() { WeakReference wr = null; new Action(() => { var subscriber = new TestSubcriber(); wr = new WeakReference(subscriber); subscriber.SubscribeToTestMessages(); })(); GC.Collect(); GC.WaitForPendingFinalizers(); var pub = new TestPublisher(); pub.Test(); Assert.IsFalse(wr.IsAlive); // The Action target and subscriber were the same object, so both could be collected }