. net TestScheduler——执行立即调度的事件

本文关键字:调度 事件 TestScheduler 执行 net | 更新日期: 2023-09-27 18:16:46

当我这样做时:

testScheduler.Schedule("Hello world",(scheduler, state) => Console.WriteLine(state));
testScheduler.AdvanceTo(testScheduler.Now);

我在VirtualTimeSchedulerBase:

中键入这段代码
public void AdvanceTo(TAbsolute time)
{
  int num = this.Comparer.Compare(time, this.Clock);
  if (num < 0)
    throw new ArgumentOutOfRangeException("time");
  if (num == 0)
    return;

num == 0为真,退出该方法。

我可以调用testScheduler.Start(),我的动作将执行。但是TestScheduler将继续执行其队列中的所有内容。而我希望它在当前时间停止执行操作。

我在TestScheduler上看不到任何其他方法可以让我得到我想要的行为。

这是一个错误,还是正确的行为,但我错过了什么?

编辑:

我误解了。TestScheduler不执行操作,直到之后的日期,他们被安排。

调度操作立即调度它的当前值testScheduler.Now。所以直到Now + 1 .

才会执行。
  var testScheduler = new TestScheduler();
  var due = new DateTime();
    testScheduler.Schedule("Hello world", due, (scheduler, s) =>
  {
    Console.WriteLine(s);
    return Disposable.Empty;
  });
  testScheduler.AdvanceTo(due.Ticks);
  // Nothing has happened
  testScheduler.AdvanceTo(due.Ticks+1);
  // -> "Hello world"

这仍然不是我想要的行为,但这就是。

. net TestScheduler——执行立即调度的事件

您可能需要考虑如何使用TestScheduler:

It 通常会在适当的时间执行。例如,以下代码将写入控制台:

var scheduler = new TestScheduler();
scheduler.Schedule(
    TimeSpan.FromTicks(100),
    () => Console.WriteLine("Hello"));
scheduler.AdvanceTo(100);

然而,TestScheduler只会在移动时间时检查它的队列。因此,如果您安排一个操作,您需要通过AdvanceByAdvanceToStart移动时间,以使其处理队列。当它运行时,它将处理截至当前时间的所有内容。例:尽管调度"过去",即使这样也会输出到控制台:

var scheduler = new TestScheduler();
scheduler.AdvanceTo(TimeSpan.FromTicks(100).Ticks);
scheduler.Schedule(
    DateTime.MinValue + TimeSpan.FromTicks(50),
    () => Console.WriteLine("Hello"));
Console.WriteLine("No output until the scheduler is given time...");
scheduler.AdvanceBy(1);

TestScheduler的习惯用法通常包括将所有工作排队,然后通过Start()调用运行到完成,然后检查预期状态。使用AdvanceBy, AdvanceTo往往是为了更苛刻的测试场景,你需要测试一些中间状态-即使这样,你通常排队所有首先在适当的时间,然后AdvanceByAdvanceTo你感兴趣的时间,检查状态,然后再次使用AdvanceBy, AdvanceToStart

你不想做的通常是队列工作,运行一点,队列更多的工作,运行一点-特别是如果你的调度没有到期时间。然后你就会遇到这里的问题。

这并不是说在您的特定场景中这可能是不可避免的-例如,如果您需要决定在特定时间之后安排什么-但是考虑您是否可以提前设置所有内容,因为它可能会导致更干净的测试代码,更紧密地遵循Arrange Act Assert模式。

我尝试通过调度来安排,然后通过移动时间来行动,然后断言结果

使用AdvanceBy(1)将调度器提前1个刻度。调度程序只在时钟实际前进时执行事件。

不同的调度程序在为立即执行调度时表现不同。他们中的一些人真的会立即执行。有些人把它放在一个队列中,在第一个可用的机会执行。

在这种情况下,TestScheduler没有一个好的行为方式,除非API被修改,让你告诉它应该以哪种方式行事。

Start方法将执行计划的所有内容。您可以调度Stop方法调用,在给定的点暂停执行。

        var testScheduler = new TestScheduler();
        var due = new DateTime();
        testScheduler.Schedule("Hello world", due, (scheduler, s) =>
        {
            Console.WriteLine(s);
            return Disposable.Empty;
        });
        testScheduler.Schedule(due.Ticks + 1, (scheduler, s) => testScheduler.Stop());
        testScheduler.Schedule("Do more stuff", due.AddMinutes(1), (scheduler, s) => Console.WriteLine(s));
        testScheduler.Start();
        Assert.IsFalse(testScheduler.IsEnabled);
        Assert.AreEqual(due.Ticks + 1, testScheduler.Clock);