【问题标题】:Waiting for all threads to finish writing in ConcurrentDictionary等待所有线程完成在 ConcurrentDictionary 中的写入
【发布时间】:2015-02-20 08:55:59
【问题描述】:

有一个并发字典,它从不同来源收集信息,每分钟刷新一次,并将收集到的数据传递给另一个处理程序。

var currentDictionarySnapshot = _currentDictionary;
_currentDictionary = new ConcurrentDictionary<int, string>();
return new ReadOnlyDictionary<int, string>(currentDictionarySnapshot);

我需要让currentDictionarySnapshot 等待所有对其有引用的线程完成写入并在之后创建新的ReadOnlyDictionaryConcurrentDictionary 本身是否支持它,如果不支持,我该如何提供?

【问题讨论】:

  • 你可以考虑使用Task.WhenAll(Task1, Task2,...);方法
  • 我的写法不是异步的,就算是异步的,也分不清主字典和快照的任务。

标签: c# multithreading concurrency concurrentdictionary


【解决方案1】:

从概念上讲,您似乎需要ReaderWriterLockSlim。 “读者”将是写入字典的线程。 “writer”是复制字典的线程。

请注意,内置的 RWL 无法扩展。它们只是在内部锁定每个操作的某些数据结构。这破坏了 ConcurrentDictionary 的可扩展性属性,它通过锁条带化进行扩展。

【讨论】:

    【解决方案2】:

    好吧,我提出的问题的解决方案是使用 ManualResetEventSlim 创建类并为其添加计数器。当阅读时间快到时,我会像使用 ConcurrentDictionary 一样制作此类的快照,然后等待计数器变为 0。

    【讨论】:

    • 您如何确保在计数降至零后没有其他作者出现?无论如何,这不是一个答案,因为它太模糊了。
    • 我制作快照并用一个新的替换这个类的实例。一位老作家将留在他的作家身边,让他们完成。
    • 复制快照不是即时的。你会得到一本随着时间的推移而被“抹黑”的字典。无论如何,这并不能回答如何等待写入完成的问题。即使您是 OP,您的答案也与其他答案的标准相同。
    • 这不是通过复制进行快照,我创建了另一个对字典的引用并从中创建只读字典。我让旧变量引用一个新的空字典,所以所有新作家都会来到一个新的。我无法粘贴我的解决方案的整个代码,因为它受到我的雇主的限制。但我的回答会帮助我解决我的问题,我认为这就是重点。
    • 创建另一个引用不会阻止写入者写入旧字典。他们可能还有旧的裁判。你需要回答被问到的问题。这是您选择的最终方法并不重要。
    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多