C#计时器和线程安全

时间:2011-03-19 17:22:23

标签: c# synchronization timer

我有一个带有一组对象的C#类,每个对象代表一个与外部设备的开放连接。在n个空闲时间之后,连接默认超时,我想避免。我打算利用一个每n-2个空闲时间跳一次的计时器,一个回调调用一个方法来触摸每个对象并有效地重置超时。

该类需要在Windows窗体和非基于窗体的项目中都可用,因此我正在考虑使用System.Timers.Timer和一个锁来限制任何其他线程在超时重置期间访问该阵列。

使用计时器会引入线程安全隐患,例如:如果其中一个对象在确定存在对象的计时器回调和重置其超时之间被破坏,则将尝试读取未初始化的存储器。但是,我的问题是在类中的许多地方访问该数组。在计时器回调正在进行时,锁应该阻止对阵列的所有访问,如下所示:

class MyClass
{
    private System.Timers.Timer timer;
    private object locker = new object();

    public void Run()
    {
        timer = new System.Timers.Timer();
        timer.Interval = 21600000;  //6 hours
        timer.Elapsed += AccessArrayCallback;
        timer.Start();
    }

    public void AccessArrayCallback(object sender, EventArgs e)
    {

        timer.Enabled = false;
        lock (locker)
        {
            /*  

            if (called by timer) 
            {  
                iterate through array and reset connections;
            }
            else 
            {
                Call appropriate function that reads/writes array using EventArgs delegate   
            }

            */
        }
        timer.Enabled = true;

    }
}

在我继续这种方法之前的一些问题:

  1. 这种问题是否有既定的模式/更优雅的方法?

  2. 在EventArgs中使用委托是否正确?要求访问数组的类中的任何其他方法都将调用回调并正确填充EventArgs。

  3. 提前致谢。

1 个答案:

答案 0 :(得分:3)

由于锁是私有对象,系统的其他部分将无法访问它以实现所需的线程安全级别。这就是为什么Concurrent Bag和它的朋友被创建的原因。代理部分虽然很好。