C#定时器和线程安全

C#定时器和线程安全,c#,synchronization,timer,C#,Synchronization,Timer,我有一个C#类,它有一个对象数组,每个对象表示与外部设备的开放连接。默认情况下,连接在n个空闲小时后超时,这是我想要避免的。我计划使用一个每n-2个空闲小时触发一次的计时器,并使用一个回调调用一个方法来触摸每个对象并有效地重置超时 该类需要在Windows窗体和非基于窗体的项目中都可用,因此我正在考虑使用System.Timers.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;

    }
}
在我继续使用此方法之前,有几个问题:

  • 对于这类问题是否有一种既定的模式/更优雅的方法

  • 在EventArgs中使用委托是否正确?类中需要访问数组的任何其他方法都将调用回调并适当地填充EventArgs


  • 提前感谢。

    由于锁是一个私有对象,系统的其他部分将无法访问它以达到您所需的线程安全级别。这就是为什么和它的朋友被创建。不过,学员部分还可以。

    谢谢您的回答-ConcurrentBag看起来是个不错的选择。这节省了我很多时间!我目前使用的3.5似乎不支持concurrentBag。我将看一看,但理想情况下,如果可能的话,我希望避免额外的依赖关系。哎哟,是的,这是一个Framework4对象。所需要的只是安装.NETFramework4(如果不是现在的话,你最终会在将来完成这项工作)。