У меня есть консольное приложение со следующей основной программой:
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 оба таймера вызываются только один раз (первый раз), а затем программа просто ждет, пока я ничего не введу.
Как исправить проблему, поэтому я могу скомпилировать автономную программу, которая работает правильно?
Поскольку @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();
}
Надеюсь, что следующее решение поможет!
Проблема:
Следующий код всегда работает так, как ожидалось, показывая текущее время синхронизации.
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);
}
}
Альтернативное решение: делает таймер статической переменной уровня класса