Таймер работает только в режиме отладки

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
    похоже, таймеры подавляются GC.
  • 0
    Вам нужно сохранить ссылку на таймер в качестве поля. В противном случае, GC съест это.
Показать ещё 6 комментариев
Теги:
timer
debugging
release

2 ответа

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 (объекта) заставит его работать в режиме Release также, как и ожидалось. См. Код ниже.

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню