锁定静态变量 - 定时器和事件处理程序

时间:2016-09-21 06:05:49

标签: c# multithreading timer static locking

我使用方法运行X分钟,另一个方法调用事件处理程序。这两个都将修改静态列表的状态。

以下是代码

 public class DatabaseOps
 {
  private static Timer timer = null;

  private static IDictionary<int, Model.Process> allProcessDetails = new Dictionary<int, Model.Process>();

  public DatabaseOps()
        {
          if (timer.IsNull())
            {
                timer = new Timer(5000);
                timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
                timer.Enabled = true;
                timer.AutoReset = true;
                timer.Start();
            }
        }

        // Timer event
         private async void OnTimerElapsed(object sender, ElapsedEventArgs e)
        {
            foreach (var processDetails in tempAllProcessDetails)
            {
                // Some logic
                allProcessDetails.Remove(processDetails.Key); 
                await Task.Run(() => SendProcess(processDetails.Value));
            }
        }

        // Method invoked from event handler
        public void UpdateProcess(Model.Process processDetails)
        {

            if (!allProcessDetails.ContainsKey(processDetails.ProcessID))
            {
                // Add process to allProcessDetails
                // Some logic
            }
            else
            {
                // Modify existing process in allProcessDetails
                // Some logic
            }
        }
 }

事件处理程序方法将检查进程,如果它存在,它将执行一些逻辑,如果进程不存在,那么它将使用新逻辑更新相同的进程。

计时器将每隔X个间隔运行一次,并将每个进程的当前状态发送到外部系统,并将从allProcessDetails中删除该进程。

在此,我需要确保allProcessDetails.ContainsKey(processDetails.ProcessID)中的检查代码UpdateProcessallProcessDetails.Remove(processDetails.Key)

中的删除代码OnTimerElapsed不一致

根据我的理解,添加一个锁将阻止来自使用相同代码序列创建的另一个线程的访问,但这里的Dictionary由不同的线程访问,这些线程是从不同的代码序列(定时器和事件处理程序)创建的

那么,我如何阻止事件处理程序方法访问当前在计时器方法中访问的相同密钥以进行删除。

2 个答案:

答案 0 :(得分:0)

只需使用 ConcurrentDictionary

 private static IDictionary<int, Model.Process> allProcessDetails = new ConcurrentDictionary<int, Model.Process>();

答案 1 :(得分:0)

我想你可以简单地使用ConcurrentDictionary。它是一个线程安全的字典它具有相同的构造函数和相同的ContainsKey方法,但除了Remove方法,您需要使用TryRemove方法。

链接:

https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/dd997369(v=vs.110).aspx