2011-03-19 122 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