带有延时的C#单元测试通过调试,但在构建服务器上失败
我在ASP.NET core中有一个类,它使用Threading.Timer在给定的时间间隔内运行一个小任务(因为在core中Timer.Timer不可用)。现在,我编写了一个单元测试,用于检查作业的运行时间:带有延时的C#单元测试通过调试,但在构建服务器上失败,c#,unit-testing,timer,C#,Unit Testing,Timer,我在ASP.NET core中有一个类,它使用Threading.Timer在给定的时间间隔内运行一个小任务(因为在core中Timer.Timer不可用)。现在,我编写了一个单元测试,用于检查作业的运行时间: [Fact] public async void IntervalExecutionTest() { var target = new PeriodicaBackgroundJobRunner(); var testJob = new Pe
[Fact]
public async void IntervalExecutionTest()
{
var target = new PeriodicaBackgroundJobRunner();
var testJob = new PeriodicalJobForTest();
target.Start(1/*run every second*/, testJob);
await Task.Delay(2500).ContinueWith(c =>
{
Assert.Equal(3, testJob.ExecutedCounter);
});
}
测试作业如下所示:
private class PeriodicalJobForTest : IPeriodicalJob
{
public int ExecutedCounter { get; private set; }
public void Execute(object state)
{
this.ExecutedCounter++;
}
}
public class PeriodicaBackgroundJobRunner : IPeriodicaBackgroundJobRunner
{
private Threading.Timer timer;
public void Start(int interval, IPeriodicalJob job)
{
interval = Math.Max(interval, 1) * 1000;
if (this.timer == null)
{
this.timer = new Timer(new TimerCallback(job.Execute), null, Timeout.Infinite, interval);
}
this.timer.Change(0, interval);
}
public void Stop()
{
if (this.timer != null)
{
this.timer.Change(Timeout.Infinite, Timeout.Infinite);
}
}
}
因此,在2,5秒的等待时间内,我预计它将在0,1和2上运行3次
在调试中,测试通过。但构建服务器失败,并显示“预期为3,实际为1”
为什么?有什么不同?一旦它实际部署到Azure,我在生产中也会遇到问题吗
注意:我还尝试了Thread.Sleep(),结果相同
为了防止问题实际发生在测试实现中的类上,该类如下所示:
private class PeriodicalJobForTest : IPeriodicalJob
{
public int ExecutedCounter { get; private set; }
public void Execute(object state)
{
this.ExecutedCounter++;
}
}
public class PeriodicaBackgroundJobRunner : IPeriodicaBackgroundJobRunner
{
private Threading.Timer timer;
public void Start(int interval, IPeriodicalJob job)
{
interval = Math.Max(interval, 1) * 1000;
if (this.timer == null)
{
this.timer = new Timer(new TimerCallback(job.Execute), null, Timeout.Infinite, interval);
}
this.timer.Change(0, interval);
}
public void Stop()
{
if (this.timer != null)
{
this.timer.Change(Timeout.Infinite, Timeout.Infinite);
}
}
}
嗯,不确定问题到底是什么,但它与Threading.Timer有关。当我在没有计时器的情况下重写类时,测试运行良好:
public class PeriodicaBackgroundJobRunner : IPeriodicaBackgroundJobRunner
{
private CancellationTokenSource cancellationToken;
public void Start(int interval, IPeriodicalJob job)
{
Task.Run(async () =>
{
interval = Math.Max(interval, 1) * 1000;
this.cancellationToken = new CancellationTokenSource();
while (true)
{
job.Execute(null);
await Task.Delay(interval, this.cancellationToken.Token);
}
});
}
public void Stop()
{
if (this.cancellationToken != null)
{
this.cancellationToken.Cancel();
}
}
}
嗯,不确定问题到底是什么,但它与Threading.Timer有关。当我在没有计时器的情况下重写类时,测试运行良好:
public class PeriodicaBackgroundJobRunner : IPeriodicaBackgroundJobRunner
{
private CancellationTokenSource cancellationToken;
public void Start(int interval, IPeriodicalJob job)
{
Task.Run(async () =>
{
interval = Math.Max(interval, 1) * 1000;
this.cancellationToken = new CancellationTokenSource();
while (true)
{
job.Execute(null);
await Task.Delay(interval, this.cancellationToken.Token);
}
});
}
public void Stop()
{
if (this.cancellationToken != null)
{
this.cancellationToken.Cancel();
}
}
}
如果将
async void
更改为async Task
,问题是否仍然存在?如果将async void
更改为async Task
,问题是否仍然存在。。。。。。。。