2011-03-19 63 views
1

我有一个C#类的对象数组,每个对象代表一个开放的连接到外部设备。在我想要避免的n个空闲时间之后,连接默认超时。我打算利用一个计时器,每隔n-2个空闲时间出发一次,用一个回调函数调用一个方法来触摸每个对象并有效地重置超时时间。C#计时器和线程安全

该类需要在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。

在此先感谢。

回答

2

由于锁是一个私人对象,因此系统的其他部分将无法访问它以达到所需级别的线程安全。这就是为什么Concurrent Bag和它的朋友被创建。代表部分如果罚款,但。

+0

感谢您的回答 - ConcurrentBag看起来像要走的路。这为我节省了很多时间! – pdm2011 2011-03-19 18:46:32

+0

我目前使用的3.5似乎并不支持concurrentBag。我将看看http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx,但理想情况下,如果可能的话,我想避免附加的依赖关系。 – pdm2011 2011-03-19 18:57:35

+0

哎哟,是的,它是一个框架4的对象。所需要的只是安装.net framework 4(如果不是现在,你最终最终会做这件事)。 – 2011-03-19 22:03:39