Hos*_*Aly 14 .net c# garbage-collection reference timer
文档System.Threading.Timer说我应该为它保留一个实时参考,以避免它被垃圾收集.但是我应该在哪里这样做?我main很简单,我不知道在哪里保留参考:
class Program {
static void Main() {
new System.Threading.Thread(myThreadStart).Start();
new System.Threading.Timer(myTimerCallback, new MyStateObject(), 0, 5000);
}
}
Run Code Online (Sandbox Code Playgroud)
我想过保持在参考static该领域Program类,假设static领域没有得到收集,直到应用程序结束.但我不确定这是最好的方法,所以我很感激你的建议.
Jon*_*eet 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);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为实际代码更复杂 - 在这种情况下,使用其他答案中建议的私有静态变量可能是要走的路.这实际上取决于使用情况.我个人不希望创建静态字段只是为了防止收集某些内容(如上所述),但有时它实际上是唯一的方法.
原(坏)答案:
如果你真的想在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);
}
}
Run Code Online (Sandbox Code Playgroud)