2016-05-16 18 views
0
System.Timers.Timer timer= new System.Timers.Timer(1); 
      timer.AutoReset = true; 
      timer.Elapsed += (s, e) => 
      { 
       Console.WriteLine("fired"); 
      }; 
timer.Start(); 

イベントは一貫してデバッグモードで発生し、一貫してリリースモードでは発生しません。私はコンパイラの最適化を無効にしようとしましたが、それは役に立たなかった。Systems.Timers.Timerはデバッグでは動作しますが、リリースではありません。

私は4.6フレームワーク

+1

クラスレベルの静的変数タイマ作っているが、それは 'Console.WriteLine'がリリースモードで動作していないことは可能ですか?私はコンソールに問題があったので尋ねます。WriteLineは1つの設定でVS出力ウィンドウにログを記録しますが、別の設定ではログアウトしません(理由は分かりません)。あなたはタイマーを非難する前にチェックする価値があるかもしれません。 – adv12

+0

リリースモードでタイマーを起動するコードブロックが実行されていますか?また、あなたの質問にasp.netというタグを付けました。おそらく、あなたのアプリケーションドメインはシャットダウンしていますか? –

+0

タイマーが実行されていることを確認するにはどうすればよいですか?私はそれが正しい間隔で作成されていることを知っています。また、これがASPに関連しているかどうかはわかりませんが、余分な情報が傷つくことはないと思いました。私のアプリドメインがリリースではシャットダウンされていて、デバッグではなくなっているのは間違いありませんか? – blenddd

答えて

3

あなたのタイマーは、おそらく罰金ですが、欠陥があるテストのあなたの方法asp.net MVCアプリケーションの.NETでこれを実行しようとしています。

ASP.NETアプリケーションでリリースモードのConsole.WriteLineに書き込まれたデータは失われます。この質問への回答を参照してください。Where does Console.WriteLine go in ASP.net production environment?

実際にConsole.WriteLineを使用する場合は、Console.SetOutを使用して出力をファイルにリダイレクトできます。

また、timerオブジェクトは、メソッドが完了するとすぐに破棄されるので、メソッド内で宣言されていないことを確認してください。

+0

私は例外をスローすることを含め、さまざまなことを試みました...リリースビルドでは何も起こりませんし、デバッグはまだうまく動作します。 – blenddd

+1

タイマのElapsedイベントは別のスレッドで実行されます。例外をキャッチするものはありません。そのため、スレッドは死にますが、アプリケーション全体ではなくなります。処理されない例外*がWindowsアプリケーションイベントログに表示される可能性があります。 –

+0

私はアプリケーションの起動時にこれを持っているので、アプリケーションは例外をスローする必要があります。デバッグモードでは発生しますが、リリースでは発生しません。 – blenddd

0

タイマーは1msに設定されています。 "解像度"(タイマーがチェックされる間隔)は通常約15msであるため、予測できない結果が生じる可能性があります。タイマーの動作をテストしようとしているのであれば、おそらくそれを20ms以上に増やします。

私はこれをテストしました。 500msの間、1msのインターバルが32回、一貫して15msごとに1回、一貫して実行されました。これはデバッグとリリースで同じでした。例外は投げられませんでした。代わりに、私はグローバルにアクセスConcurrentQueue時にタイマーが経過するに項目を追加することをお勧めしたいのコンソールへの書き込みの

(これはテスト/実験のためだけであるから。)

そして、Webページ上のあなたは可能性があり、出力内容キューのタイマーを最初に停止して、アイテムをキューに入れないようにすることができます。 (または、より長い間隔を使用してください)

+0

これを試してみましたが、役に立たなかった – blenddd

0

次の解決策が役立ちますように!

問題:

次のコードは、常に現在の時刻を示すことによって、期待通りに動作します。あなたはリリースモードで同じコードを実行した場合

class Program 
{ 
     static void TimerProcedure(object param) 
     { 
      Console.Clear(); 
      Console.WriteLine(DateTime.Now.TimeOfDay); 

      GC.Collect(); 

     } 

     static void Main(string[] args) 
     { 
      Console.Title = "Desktop Clock"; 
      Console.SetWindowSize(20, 2); 
      Timer timer = new Timer(TimerProcedure, null, 
       TimeSpan.Zero, TimeSpan.FromSeconds(1)); 
      Console.ReadLine(); 
     } 
    } 

しかし、それだけで最初に現在の時刻を示しているが、それはそれ以降更新されません。

ソリューションは、GC.KeepAlive(オブジェクト)を追加することにより、簡単な微調整は予想通り、それはまた、リリースモードで動作するようになります。以下のコードを参照してください。あなたの特定の問題に来て

class Program 
    { 
     static void TimerProcedure(object param) 
     { 
      Console.Clear(); 
      Console.WriteLine(DateTime.Now.TimeOfDay); 
      #region Hidden 
      GC.Collect(); 
      #endregion 
     } 

     static void Main(string[] args) 
     { 
      Console.Title = "Desktop Clock"; 
      Console.SetWindowSize(20, 2); 
      Timer timer = new Timer(TimerProcedure, null, 
       TimeSpan.Zero, TimeSpan.FromSeconds(1)); 
      Console.ReadLine(); 
      GC.KeepAlive(timer); 
     } 
    } 

、タイマ変数のスコープはメソッドにローカルであるかどうかを確認。それが本当であれば、上記のように生き続けることができます。

代替ソリューション:

関連する問題