System.Threading.Timer
的文档说我应该为它保留一个实时参考,以避免它被垃圾收集。但是我应该在哪里这样做?我的main
非常简单,我不知道在哪里保留引用:
class Program {
static void Main() {
new System.Threading.Thread(myThreadStart).Start();
new System.Threading.Timer(myTimerCallback, new MyStateObject(), 0, 5000);
}
}
我考虑将引用保留在static
类的Program
字段中,假设在应用程序结束之前不会收集static
字段。但我不确定这是最好的方法,所以我很感激你的意见。
答案 0 :(得分:18)
如果你的Timer是一个应用程序级别的对象,那么将它作为Main类的私有静态成员是没有错的。无论如何,这就是我要做的。
答案 1 :(得分:12)
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);
}
}
我认为真正的代码更复杂 - 在这种情况下,使用其他答案中建议的私有静态变量可能是要走的路。这实际上取决于使用情况。我个人不希望创建静态字段只是为了防止收集某些东西(如上所述),但有时它实际上是唯一的方法。
原创(不好)回答:
如果您真的想在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);
}
}
答案 2 :(得分:4)
我认为保持是您班级的私有静态字段是可以的。
我会将此引用保留为静态字段,而不是使用垃圾收集器。