gpt4 book ai didi

c# - 响应式扩展测试调度程序模拟时间流逝

转载 作者:行者123 更新时间:2023-12-02 06:43:59 25 4
gpt4 key购买 nike

我正在使用 .Schedule(DateTimeOffset, Action>) 内容来处理 RX 调度程序类。基本上我有一个可以再次安排自己的预定操作。

代码:

public SomeObject(IScheduler sch, Action variableAmountofTime)
{
this.sch = sch;
sch.Schedule(GetNextTime(), (Action<DateTimeOffset> runAgain =>
{
//Something that takes an unknown variable amount of time.
variableAmountofTime();

runAgain(GetNextTime());
});
}

public DateTimeOffset GetNextTime()
{
//Return some time offset based on scheduler's
//current time which is irregular based on other inputs that i have left out.
return this.sch.now.AddMinutes(1);
}

我的问题是关于模拟variableAmountofTime可能花费的时间并测试我的代码是否按预期运行并且仅触发按预期调用它。

我尝试过在委托(delegate)内提前测试调度程序的时间,但这不起作用。我编写的代码示例不起作用。假设 GetNextTime() 只是安排一分钟时间。

[Test]
public void TestCallsAppropriateNumberOfTimes()
{
var sch = new TestScheduler();

var timesCalled = 0;

var variableAmountOfTime = () =>
{
sch.AdvanceBy(TimeSpan.FromMinutes(3).Ticks);
timescalled++;
};

var someObject = new SomeObject(sch, variableAmountOfTime);

sch.AdvanceTo(TimeSpan.FromMinutes(3).Ticks);

Assert.That(timescalled, Is.EqualTo(1));
}

由于我想要进入 future 3 分钟,但执行需要 3 分钟,所以我希望看到这只触发 1 次......而不是触发 3 次。

如何使用测试调度程序模拟执行过程中花费时间的某些事情。

最佳答案

好问题。不幸的是,Rx v1.x 和 Rx v2.0 Beta 中目前不支持(但请继续阅读)。让我向您解释嵌套 Advance* 调用的复杂性。

基本上,Advance* 意味着启动调度程序运行工作直到指定的点。这涉及在代表虚拟调度程序中的时间流的单个逻辑线程上按顺序运行工作。允许嵌套 Advance* 调用会引发一些问题。

首先,嵌套 Advance* 调用是否应该导致嵌套工作循环运行?如果是这种情况,我们将不再模仿单个逻辑执行线程,因为当前工作项将被中断以支持运行内部循环。事实上,Advance* 会导致隐式屈服,其中 Advance* 调用之后的其余工作(现在到期)将不允许运行,直到所有嵌套工作都已处理完毕。这导致了 future 的工作不能依赖(或等待)过去的工作来完成其执行的情况。一种出路是引入真正的物理并发,这从一开始就击败了虚拟时间和历史调度程序的各种设计点。

或者,如果嵌套的 Advance* 调用以某种方式与最顶层的工作循环调度调用(Advance* 或 Start)进行通信,它可能需要延长其到期时间,因为嵌套调用已要求前进到超出原始值的点截至日期。现在各种事情都变得奇怪了。时钟不反射(reflect)从 Advance* 返回后的变化,并且最顶层的调用不再在可预测的时间完成。

对于Rx v2.0 RC(下个月推出),我们研究了这个场景,并认为 Advance* 不适合模拟“时间滑移”,因为它需要一个重载的含义取决于调用它的上下文。相反,我们引入了一种Sleep 方法,可用于将时间从任何上下文中提前,而不会产生运行工作的副作用。将其视为设置 Clock 属性但防止时间倒流的一种方法。这个名字也清楚地反射(reflect)了意图。

除上述之外,为了减少嵌套 Advance* 调用无效的意外因素,我们让它检测这种情况并在嵌套上下文中抛出 InvalidOperationException。另一方面, sleep 可以从任何地方调用。

最后一点。事实证明,我们在 Rx v2.0 RC 中所做的关于时间处理的工作需要完全相同的功能。一些测试需要一种确定性的方法来模拟由于执行用户代码而导致的时间滑动,该时间可能会花费任意长的时间(想想 OnNext 处理程序,例如 Observable.Interval)。

希望这会有所帮助...请继续关注我们在未来几周内发布的 Rx v2.0 RC!

-Bart(接收团队)

关于c# - 响应式扩展测试调度程序模拟时间流逝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10744100/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com