文档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
领域没有得到收集,直到应用程序结束.但我不确定这是最好的方法,所以我很感激你的建议.
如果你的Timer是一个应用程序级对象,那么将它作为Main类的私有静态成员是没有错的.无论如何,这就是我要做的.
编辑:我原来的答案是垃圾.真的很垃圾.我一直在这里解释为什么它是垃圾 - 它在评论中,但它们已被删除了答案.
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); } }