2017-07-14 80 views
1

我有一個ASP.NET核心類,它使用Threading.Timer在給定的時間間隔內運行一個小任務(因爲Timer.Timer在Core中不可用)。現在,我寫了一個單元測試,檢查工作多少時間運行:具有時間延遲的C#單元測試通過調試但在構建服務器上失敗

[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++; 
     } 
    } 

所以用2.5秒的等待時間我期望它在0,1和2上運行3次。

在調試中測試通過。但是,構建服務器失敗,並說「預計3,實際1」。

怎麼回事?那裏有什麼不同?一旦實際部署到Azure後,我是否也會遇到生產問題?

注意:我也嘗試使用Thread.Sleep(),結果相同。

萬一這個問題可能有類實際上是在測試實現,類看起來是這樣的:

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); 
     } 
    } 
} 
+0

問題仍然存在,如果您將'async void'更改爲'async Task'? – Kote

+0

它確實........ –

回答

0

好,不知道是什麼問題實際上是,但它是與線程。計時器。當我重寫類沒有計時器時,測試工作正常:

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(); 
     } 
    } 
} 
相關問題