当前位置: 首页 > 知识库问答 >
问题:

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

陈飞
2023-03-14

我有一个类,其中一个方法运行了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间隔运行一次,并将每个进程的当前状态发送到外部系统,并将从allProcess详细信息中删除该进程。

在这里,我需要确保UpdateProcess中的检查代码allProcessDetails.ContainsKey(processDetails.ProcessID) 中的删除代码 allProcessDetails.remove(process Details.Key)不冲突

根据我的理解,添加一个锁会阻止使用相同代码序列创建的另一个线程的访问,但这里字典是由不同代码序列创建的不同线程(计时器和事件处理程序)访问的

那么,如何防止事件处理程序方法访问当前可以在用于移除的计时器方法中访问的相同密钥。

共有2个答案

盖马鲁
2023-03-14

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

链接:

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

https://msdn.microsoft.com/en-us/library/dd997369. aspx

苏硕
2023-03-14

只需使用并发字典:

 private static IDictionary<int, Model.Process> allProcessDetails = new ConcurrentDictionary<int, Model.Process>();
 类似资料:
  • 我在C中做了一个关于线程、锁和条件变量的练习。我需要编写一个程序来获取数据,将其转换为一个链表,启动3个线程,每个线程为列表中的每个节点计算结果,主线程在evreyone完成后打印结果。 这是主要功能: 请注意,create_numbers功能正常工作,列表按预期工作。 以下是启动线程和线程功能代码: 请注意,self_id用于调试目的。 我的主要问题是分工合作。每个线程从全局链表中获取一个元素,

  • 问题内容: 我目前正在研究Socket.io的Java实现,可从此处获取:netty- socketio 我已经启动并运行了服务器,并且它在客户端和服务器之间很好地接收/发送消息,但是我需要让某些消息被接收时触发事件,这就是我的困惑。 这是我的代码: } 本质上,我想发生的是从客户端收到特定消息时,我需要另一个类中的函数才能运行。我花了持续两个小时阅读,,和事件处理程序,但我真的不知道如何处理此问

  • 问题内容: 我已经定义了一个对象并声明了一个静态变量。在该方法中,当我尝试打印实例和类变量时,两者都打印相同的值。 不是实例变量吗?它应该打印0而不是50吗? 问题答案: 不,只有一个变量-您尚未声明任何实例变量。 不幸的是,Java允许您访问静态成员,就像通过相关类型的引用访问静态成员一样。这是IMO的设计缺陷,某些IDE(例如Eclipse)允许您将其标记为警告或错误- 但这是语言的一部分。您

  • 如果我在java类X中不使用任何setter/getter。当一个线程a具有类X的类级锁时,另一个线程B是否可以直接更改我的静态变量?? 假设线程A现在有类级锁。我可以从另一个线程B执行X.static\u variable=11吗? 我正在编写一段代码,以在java中获得死锁。 公共类A实现Runnable{ } } 公共类B实现Runnable{ } 但得到以下结果: 第二个有对象b的钥匙和等

  • django.contrib.staticfiles 从你的应用(和其他你指定的地方)收集所有静态文件到同一个地方,这样产品就能很容易的被维护 看看这里 对于静态文件的应用和一些用法示例的介绍,请参阅管理静态文件(CSS,图像) . 如果你想知道如何部署静态文件, 请参阅 部署静态文件. 设置 查看staticfiles settings了解更多设置细节 STATIC_ROOT STATIC_UR

  • 13.4.1. START TRANSACTION, COMMIT和ROLLBACK语法 13.4.2. 不能回滚的语句 13.4.3. 会造成隐式提交的语句 13.4.4. SAVEPOINT和ROLLBACK TO SAVEPOINT语法 13.4.5. LOCK TABLES和UNLOCK TABLES语法 13.4.6. SET TRANSACTION语法 13.4.7. XA事务 MyS