c# - System.Timer 作为单例

标签 c# multithreading design-patterns timer singleton

我有许多线程不断读取的数据。该数据需要每天更新。

我的方法是使用 ReaderWriterLockSlim 来管理对数据的访问。每天晚上,第一个检测日期变化的线程都会对数据应用 WriteLock 并更新它。

为了避免不断检查换日事件。理想情况下,我希望创建一个 System.Timer 对象作为单例,并让它自动启动,然后每 24 小时执行一次。

这是我的方法:

首先,我扩展了 System.Timers 以在 init 上执行回调。

using System.Timers;

namespace Utilities
{
    class AutoStartTimer : Timer
    {
        public AutoStartTimer(ElapsedEventHandler callback, int period):base(period)
        {
            callback(null, null);
            AutoReset = true;
            Elapsed += callback;
            Enabled = true;
        }
    }
}

然后我在需要它的单例处声明了它。

private static AutoStartTimer _loadDataTimer = 
                                new AutoStartTimer(DataLoader, 86400000); // Daily

到目前为止,这种方法对我来说很有效。但是我想知道是否有更好的方法来实现单例计时器,该计时器在初始化时执行一次,然后在设定的时间内执行,或者是否有人能够在不扩展 Timer 类的情况下更有效地执行此操作。

我需要在当前的项目中使用其中的许多方法,因此我想确保我使用的是好的方法。

谢谢。

最佳答案

使用静态类:

public static class DayManager
{
     public static readonly object SyncRoot = new object();

     private static readonly Timer dayTimer;

     static DayManager()
     {
         dayTimer = new Timer { AutoReset = true; Enabled = true; Interval = 86400000d };
         dayTimer.Elapsed += OnDayTimerElapsed;
     }

     protected void OnDayTimerElapsed(object sender, ElapsedEventArgs e)
     {
         if(DayPassedEvent != null)
         {
             DayPassedEvent(this, null);
         }
     }

     public event EventHandler DayPassedEvent;
}

现在,在每个线程中,您应该订阅 DayPassedEvent 并使用 Monitor.TryEnter(DayManager.SyncRoot) 来获取计时器管理类上的锁。这意味着只有一个线程应该继续尝试更新数据,其余线程应该无法获得锁并继续其生命。我会将其具体实现留给您。

或者,您可以从此处的计时器管理类中删除 SyncRoot 并使用另一个,就像您已经在做的那样,我只是提供它仅供引用。

关于c# - System.Timer 作为单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13288695/

相关文章:

c# - 有没有更好的方法将 Lambda 与 N 组一起使用?

node.js - 将 babel 与 Node 集群结合使用

java - 为什么 Java 中的每个对象都隐式扩展 java.lang.Object 类?

string - 在文件中查找转义字符

c# - 批量插入问题

c# - 将事件传递给 ViewModel 的最佳方式是什么?

c# - 从 DotPeek(或等价物)重新创建解决方案/项目?

python - 我正在尝试使用python中的TCP创建客户端服务器模型以进行文件共享。

.net - 您能确保所有线程都以特定文化启动吗?

java - 其中哪一个是 Memento 设计模式的正确实现?