Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 系统。计时器作为单例_C#_Multithreading_Design Patterns_Timer_Singleton - Fatal编程技术网

C# 系统。计时器作为单例

C# 系统。计时器作为单例,c#,multithreading,design-patterns,timer,singleton,C#,Multithreading,Design Patterns,Timer,Singleton,我有很多线程不断读取的数据。这些数据需要每天更新 我的方法是使用ReaderWriterLockSlim来管理对数据的访问。每天晚上,检测白天变化的第一个线程对数据应用WriteLock,并对其进行更新 以避免对日变化事件进行持续检查。理想情况下,我希望创建一个System.Timer对象作为单例,并让它自动启动,然后每隔24小时执行一次 这就是我的方法: 首先,我扩展了System.Timer以在init上执行回调 using System.Timers; namespace Utiliti

我有很多线程不断读取的数据。这些数据需要每天更新

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

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

这就是我的方法:

首先,我扩展了System.Timer以在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;
}
现在,在每个线程中,您都应该订阅DayPasseEvent并使用Monitor.TryEnter(DayManager.SyncRoot)获取计时器管理类上的锁。这意味着只有一个线程应该继续尝试更新数据,其余线程应该无法获得锁并继续使用它们的生命。我将把这件事的具体实施交给你


或者,您可以从这里的计时器管理类中删除SyncRoot,并使用另一个,因为您已经在这样做了,我只是提供它仅供参考。

我有更好的方法供您使用。使用Codeplex的轻量级调度程序库

轻量级任务调度库,允许您在指定的时间或间隔轻松地调度回调方法的调用。支持.NET3.5和Silverlight

该库允许您只需几行代码即可将Flexible调度功能包含到应用程序中,并提供一个流畅的API来配置作业:

链接:

其他办法:

.NET中的任务计划程序类:


为什么不将静态计时器实例添加到另一个管理该实例的类中?这不需要每次创建该类的实例时都检查initilise/计时器是否为null?如何使用计时器防止并发问题?我正在使用并发锁。计时器是为了避免检查时间。我在问题的结尾添加了我认为达沃所建议的内容。-我还没试过。我不需要每天跑步,只要24小时一次。。。不过,我确实喜欢将此解决方案作为在特定时间进行更新的一种方式。谢谢嗯,措辞很尴尬,因为它不是在0:00运行,但它只是每24小时运行一次。当我提供示例解决方案时,我不太注意适当的命名:杰斯特注意到了我自己。解决方案正是我想要的。静态类中的实例方法和变量?