也就是说,我有一个包含静态System.Threading.Timer的类,我想在所有对象中同步定时器。一个例子如下,我想要实现的是让所有对象同时调用DoStuff()
:
public class TestClass {
public static Timer timer;
public TestClass() {
TimerCallback callback = DoStuff;
timer = new Timer(callback, timer, 0, 500);
}
public void DoStuff(object source) {
// Do stuff
}
}
答案 0 :(得分:1)
由于计时器参考存储在static
字段中,因此您一次只能使用一个计时器实例。因此,我不清楚"同步定时器[复数]" 是什么意思。
如果您希望类的每个实例在单个计时器的相同标记上执行其DoStuff()
方法,那么在我看来,正确的方法是维护单个静态处理程序,调用每个实例更新的委托实例。例如:
public class TestClass {
private static class TimerHandler
{
public static event TimerCallback TimerHandlers;
private static readonly Timer timer = new Timer(TimerHandlerCallback, null, 0, 500);
private static void TimerHandlerCallback(object state)
{
TimerHandlers?.Invoke(timer);
}
}
public TestClass() {
TimerHandler.TimerHandlers += DoStuff;
}
public void DoStuff(object source) {
// Do stuff
}
}
注意:
Timer
字段public
。timer
作为值传递给构造函数的state
参数。目前还不清楚你打算做什么。以下是所做的:第一次初始化计时器时,字段的值为null
,因此state
参数为{{1那是什么传递给处理程序的。对于null
的每个新实例,该实例将创建一个新计时器,但使用以前创建的计时器实例作为TestClass
值。在state
的每个实例中,当调用其TestClass
方法时,它将接收对前一个DoStuff()
对象实例创建的计时器的引用,或者TestClass
创建null
对象的第一个实例。TestClass
值的计时器(传递state
),然后传递计时器在调用委托时引用它自己。这对我来说比你的代码所做的更有意义。null
对象永远将被垃圾收集,因为没有机制可以从计时器事件中取消订阅对象。您可能需要考虑向您的TestClass
对象添加一个方法,该方法取消订阅该事件,以及调用代码在准备丢弃给定的TestClass
对象之前可以调用的方法。 />这是否真的需要,我无从知晓。你的问题中没有足够的背景。如果这些对象永远不需要GC,那么您可以跳过此步骤。如果您确实需要这样做,您可能需要考虑实现TestClass
作为调用方法的便捷机制(即让您的IDisposable
方法调用它),以便a)您可以使用{{ 1}}语句来处理对象的生命周期,以及b)使接口实现的存在提醒您需要手动管理对象的生命周期。在这里实现Dispose()
的一个警告(除了所有常见的其他注意事项)是你不能依赖终结器作为错误代码的备份,因为这只适用于实际的对象有资格成为GC,在这种情况下,直到你致电using
为止。IDisposable
类来简化这一过程。如果不是,您可能会发现学习如何正确使用弱引用并不值得,尤其是在事件的上下文中。再说一次,没有更多的背景,我很难说。无论哪种方式,使用弱引用的好处是事件代码保留的引用本身不会阻止对象被GC编辑。您将一个实现细节挑战替换为另一个;好处是新的挑战更加自动......一旦你解决了它,你就完成了,而不是每次你创建一个你需要清理的Dispose()
对象的实例时都要记住它后来。缺点当然是概念上,弱的引用可能比在丢弃对象之前必须清理对象的基本思想更难理解。