2014-08-28 3 views
1

У меня есть консольное приложение с помощью следующей основной программы:Таймер работает только в режиме отладки

static void Main(string[] args) 
    { 
     var timer = new System.Threading.Timer(
     e => 
      { 
      //some code here 
     }, 
     null, 
     TimeSpan.Zero, 
     TimeSpan.FromMinutes(1)); 


     var backupTimer = new System.Threading.Timer(
     e => 
     { 
      //some code here 

     }, 
     null, 
     TimeSpan.Zero, 
     TimeSpan.FromHours(24)); 

     Console.ReadLine(); 

    } 

Проблема заключается в том, что в режиме отладки он отлично работает и вызовов методов в обоих таймеров в правильном периоде, и если ввести что-то в консоли заканчивается работа программы (Console.ReadLine() для этого), но когда я запускаю программу в режиме Release, оба таймера вызываются только один раз (первый раз), а затем программа просто ждет, пока я ничего не введу.

Как исправить проблему, поэтому я могу скомпилировать отдельную программу, работающую правильно?

+0

это выглядит как таймеры подавлены с помощью ГХ. – frankie

+0

Вам нужно сохранить ссылку на таймер как поле. В противном случае GC съест его. –

+0

Почему он работает правильно в режиме отладки? – s1ddok

ответ

3

Как @SriramSakthivel предложил вам оставить ссылку на таймер в качестве поля, иначе сборщик мусора съедает ваши таймеры. так вот решение:

private static System.Threading.Timer timer; 
    private static System.Threading.Timer backupTimer; 

    static void Main(string[] args) 
    { 

     timer = new System.Threading.Timer(
     e => 
      { 
      //something 
     }, 
     null, 
     TimeSpan.Zero, 
     TimeSpan.FromMinutes(1)); 


     backupTimer = new System.Threading.Timer(
     e => 
     { 
      //something 

     }, 
     null, 
     TimeSpan.Zero, 
     TimeSpan.FromHours(24)); 

     Console.ReadLine(); 

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

Альтернативное решение: делает таймер уровня класса статической переменной

Смежные вопросы