2017-07-14 12 views
1

私は、ASP.NETコアに、Threading.Timerを使用して一定の間隔で小さなタスクを実行するクラスを持っています(Timer.Timerはコアで利用できないため)。私はそれが期待待ち時間2.5秒とそう時間遅延を伴うC#ユニットテストはデバッグに成功しませんが、ビルドサーバでは失敗します

private class PeriodicalJobForTest : IPeriodicalJob 
    { 
     public int ExecutedCounter { get; private set; } 

     public void Execute(object state) 
     { 
      this.ExecutedCounter++; 
     } 
    } 

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

仕事のテストのために次のようになります。今、私は、ジョブが実行されたどのように多くの時間をチェックするユニットテストを書きました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

は、まだ存在する問題ですか? – Kote

+0

ですね。 –

答えて

0

さて、問題は、実際にですが、それはスレッドとは何かを持っているかわかりません。タイマー。私はタイマーなしでクラスを書き直したときにテストがうまく働いた:あなたはTask`非同期 `に`非同期void`を変更した場合

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(); 
     } 
    } 
} 
関連する問題