尝试找到C#并发队列的无锁解决方案

时间:2019-06-27 17:44:09

标签: c# concurrency locking

我在C#中具有以下代码: (_StoreQueue是一个ConcurrentQueue)

        var S = _StoreQueue.FirstOrDefault(_ => _.TimeStamp == T);
        if (S == null)
        {
            lock (_QueueLock)
            {
                // try again
                S = _StoreQueue.FirstOrDefault(_ => _.TimeStamp == T);
                if (S == null)
                {
                    S = new Store(T);
                    _StoreQueue.Enqueue(S);
                }
            }
        }

系统正在实时(非常高的频率,大约每秒300-400次呼叫)收集数据,并将其放入代表5秒间隔的垃圾箱(存储对象)中。这些垃圾桶在写入时位于队列中,而在处理和写入数据时清空队列。

因此,当数据到达时,将进行检查以查看是否存在用于该时间戳记的bin(四舍五入),如果没有,则创建一个。

由于这是相当多的多线程,因此系统采用以下逻辑:

如果有垃圾箱,则用于放置数据。 如果没有bin,则会启动一个锁,并在该锁内进行一次检查,以确保在此期间它不是由另一个线程创建的。如果仍然没有垃圾箱,则会创建一个垃圾箱。

在此系统中,该锁大约每2k次使用一次

我试图查看是否有一种方法可以删除该锁,但这主要是因为我认为必须有一个更好的解决方案,即再次检查。

我一直在考虑的另一种方法是提前创建空垃圾箱,这将完全消除对任何锁的需求,但是对正确垃圾箱的搜索将变得较慢,因为它必须扫描预先构建的列表垃圾桶找到合适的垃圾桶。

1 个答案:

答案 0 :(得分:2)

使用No camera is rendering to this display可以解决您遇到的问题。在这里,我假设您的ConcurrentDictionary属性为double类型,但是只要您使TimeStamp键与该类型匹配,它就可以为任何类型。

ConcurrentDictionary