野田时间和循环操作(c#)

野田时间和循环操作(c#),c#,timer,delay,nodatime,C#,Timer,Delay,Nodatime,我正在尝试编写一个“ping”代码,每隔一分钟就会发布到某个rest服务 我最简单的“旧”方法如下: while(true) { if(cancellationToken.IsCancellationRequested) { 返回; } 等待任务延迟(TimeSpan.FromMinutes(1),cancellationToken); 尝试 { 等待PingImpl(clientId、baseUri、cancellationToken); } 捕获(例外情况除外) { _LogError(例如

我正在尝试编写一个“ping”代码,每隔一分钟就会发布到某个rest服务

我最简单的“旧”方法如下:

while(true)
{
if(cancellationToken.IsCancellationRequested)
{
返回;
}
等待任务延迟(TimeSpan.FromMinutes(1),cancellationToken);
尝试
{
等待PingImpl(clientId、baseUri、cancellationToken);
}
捕获(例外情况除外)
{
_LogError(例如,“ping{BaseUri}{Endpoint}失败”,BaseUri,Endpoint);
}
}
现在,为了对服务器的重复调用进行单元测试,我通常会在生产环境中将延迟持续时间设置为一毫秒,在生产环境中设置为一分钟(我知道,由于执行请求所需的时间,它将比每分钟轮询一次“慢”,这是可以接受的)

现在,有了#codatime,我不想把注入参数搞得一团糟,希望在IClock上得到一些扩展

等待时钟延迟(…); 然后,单元测试代码将提前假时钟并触发操作


你知道实现这种行为的优雅方法吗?

IClock
没有任何延迟的概念,它只回答了“现在是什么时间”的问题

你想要的是一种不同的抽象。在我作为Google云客户端库的一部分维护的GAX项目中,我们有:

公共接口IScheduler
{
任务延迟(TimeSpan延迟、CancellationToken CancellationToken);
}
就像
IClock
,还有一个使用
Task.Delay
的单例实现和一个使时钟提前的单例实现。我想说,随着时间的推移,测试实现已经给我们带来了很多问题,因为这是一个非常复杂的模拟过程。您不能只提前时钟,然后返回已完成的任务,因为您希望在开始和完成延迟之间的“模拟时间”内发生其他异步调用

当然,你可能会有更简单的要求——如果你没有其他事情,你可能只是能够提前完成。但是,要注意这一点的局限性,因为其他异步操作不会同时发生

这里的基本思想是非常有用的,但它的实现确实很混乱