如何解决Noda时间和循环操作C#
我正在尝试编写“ ping”代码,每分钟一次将其发布到某些休息服务。
我最简单的“旧”方法将是:
while (true)
{
if (cancellationToken.IsCancellationRequested)
{
return;
}
await Task.Delay(TimeSpan.FromMinutes(1),cancellationToken);
try
{
await PingImpl(clientId,baseUri,cancellationToken);
}
catch (Exception ex)
{
_logger.LogError(ex,"ping {BaseUri} {Endpoint} Failed",Endpoint);
}
}
现在,要对重复调用服务器进行单元测试,我通常将延迟持续时间注入生产中的毫秒数和生产中的分钟数(我知道它会每分钟轮询一次“较慢”,因为执行请求所需的时间,这是可以接受的)
现在,使用#codatime,我希望不要弄乱注入参数,并希望对IClock进行一些扩展,例如
await _clock.Delay(...);
然后,单元测试代码将提前假时钟并触发操作。
您知道实现这种行为的一些优雅方法吗?
解决方法
IClock
没有任何延迟的概念-仅 回答“当前时间是什么”的问题。
您想要的是不同的抽象。在我作为Google Cloud客户端库一部分维护的GAX项目中,我们有this abstraction:
public interface IScheduler
{
Task Delay(TimeSpan delay,CancellationToken cancellationToken);
}
就像IClock
一样,有一个使用Task.Delay
的单例实现-和test implementation可以提前一个时钟。我要说的是,随着时间的流逝,测试实现给我们带来了很多问题,因为这是一件非常复杂的事情。您不能只是提前时钟然后返回已完成的任务-因为您希望在启动和完成延迟之间的“模拟时间内”发生其他异步调用。
您当然可能有更简单的要求-如果您没有其他事情要做,您也许可以提前进行。但是要意识到这一点的局限性,因为与此同时没有发生其他异步操作。
这里的基本想法是一个非常有用的想法-但实现起来确实很麻烦。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。