public void TestCancelNotification()
        {
            MockTimeSource mockTimeSource = new MockTimeSource(new DateTime(2010, 1, 1));

            using (TestSubscriber subscriber1 = new TestSubscriber()) {
                using (TestSubscriber subscriber2 = new TestSubscriber()) {
                    using (Scheduler scheduler = new Scheduler(mockTimeSource)) {
                        object handle = scheduler.NotifyIn(
                            TimeSpan.FromHours(24), subscriber1.Callback
                            );
                        scheduler.NotifyIn(TimeSpan.FromHours(36), subscriber2.Callback);

                        mockTimeSource.AdvanceTime(TimeSpan.FromHours(12));
                        scheduler.Cancel(handle);
                        mockTimeSource.AdvanceTime(TimeSpan.FromHours(24));

                        // Wait for the second subscriber to be notified. This is still a race
                        // condition (there's no guarantee the thread pool will run tasks in
                        // the order they were added), but it's the best we can do without
                        // relying on an ugly Thread.Sleep() in this test.
                        Assert.IsTrue(subscriber2.WaitForCallback(1000));
                        Assert.AreEqual(0, subscriber1.CallbackCount);
                    }
                }
            }
        }
        public void TestCancelFinalNotification()
        {
            MockTimeSource mockTimeSource = new MockTimeSource(new DateTime(2010, 1, 1));

            using (TestSubscriber subscriber = new TestSubscriber()) {
                using (Scheduler scheduler = new Scheduler(mockTimeSource)) {
                    scheduler.Cancel(
                        scheduler.NotifyIn(TimeSpan.FromHours(12), subscriber.Callback)
                        );

                    mockTimeSource.AdvanceTime(TimeSpan.FromHours(14));
                    Thread.Sleep(1);
                }
            }
        }
    public void TestCancelFinalNotification() {
      MockTimeSource mockTimeSource = new MockTimeSource(new DateTime(2010, 1, 1));
      using(TestSubscriber subscriber = new TestSubscriber()) {
        using(Scheduler scheduler = new Scheduler(mockTimeSource)) {
          scheduler.Cancel(
            scheduler.NotifyIn(TimeSpan.FromHours(12), subscriber.Callback)
          );

          mockTimeSource.AdvanceTime(TimeSpan.FromHours(14));
          Thread.Sleep(1);
        }
      }
    }
    public void TestCancelNotification() {
      MockTimeSource mockTimeSource = new MockTimeSource(new DateTime(2010, 1, 1));
      using(TestSubscriber subscriber1 = new TestSubscriber()) {
        using(TestSubscriber subscriber2 = new TestSubscriber()) {
          using(Scheduler scheduler = new Scheduler(mockTimeSource)) {
            object handle = scheduler.NotifyIn(
              TimeSpan.FromHours(24), subscriber1.Callback
            );
            scheduler.NotifyIn(TimeSpan.FromHours(36), subscriber2.Callback);

            mockTimeSource.AdvanceTime(TimeSpan.FromHours(12));
            scheduler.Cancel(handle);
            mockTimeSource.AdvanceTime(TimeSpan.FromHours(24));

            // Wait for the second subscriber to be notified. This is still a race
            // condition (there's no guarantee the thread pool will run tasks in
            // the order they were added), but it's the best we can do without
            // relying on an ugly Thread.Sleep() in this test.
            Assert.IsTrue(subscriber2.WaitForCallback(1000));
            Assert.AreEqual(0, subscriber1.CallbackCount);
          }
        }
      }
    }