РЕДАКТИРОВАТЬ: мой оригинальный ответ мусор. На самом деле мусор. Я сохранил это здесь, чтобы объяснить , почему это мусор, хотя - это в комментариях, но они были бы удалены с ответом.
GC.KeepAlive только гарантирует, что ссылка обрабатывается как корень до окончания вызова. В коде внизу этого ответа метод GC.KeepAlive будет вызван немедленно, и тогда таймер все еще будет иметь право на сборку мусора. Поскольку вновь созданный поток является потоком переднего плана, приложение будет работать, пока оно живо (в то время как таймер использует фоновый поток, который не предотвращает выход из программы). Это означает, что метод Main завершается, но приложение должно продолжать работать.
Возможно, более простым решением было бы запустить myThreadStart
в главном потоке, а не создавать новый, а затем позволить основному потоку умереть. Другими словами, простое решение будет:
using System.Threading;
class Program {
static void Main() {
Timer timer = new Timer(myTimerCallback,
new MyStateObject(), 0, 5000);
myThreadStart();
GC.KeepAlive(timer);
}
}
Я предполагаю, что код real более сложен - в этом случае использование приватной статической переменной, как предложено в других ответах, вероятно, путь. Это действительно будет зависеть от использования, хотя. Лично я предпочитаю не создавать статическое поле только для предотвращения сбора чего-либо, если есть альтернатива (как указано выше), но иногда это практически единственный способ сделать это.
Оригинальный (плохой) ответ:
Если вы действительно хотите разместить его в Main, вы можете использовать GC.KeepAlive :
using System.Threading;
class Program {
static void Main() {
new Thread(myThreadStart).Start();
Timer timer = new Timer(myTimerCallback,
new MyStateObject(), 0, 5000);
GC.KeepAlive(timer);
}
}