C# 在静态类中创建一个线程安全的词典?

C# 在静态类中创建一个线程安全的词典?,c#,.net,multithreading,dictionary,C#,.net,Multithreading,Dictionary,到目前为止,我一直在一个C#库中开发一个静态类,所有方法显然都是静态的。任何被操纵的数据都会传入,因此这是线程安全的。但是,我正在实现一个功能,它需要一个字典来统计某些字符串ID,这些ID将为每个线程生成不同的字符串ID。显然,使用类似于以下内容的内容将不会是线程安全的,因为多个线程将使用相同的字典,并扰乱其状态: private static readonly Dictionary<string, uint> MyTallies = new Dictionary<string

到目前为止,我一直在一个C#库中开发一个
静态类
,所有方法显然都是静态的。任何被操纵的数据都会传入,因此这是线程安全的。但是,我正在实现一个功能,它需要一个
字典
来统计某些字符串ID,这些ID将为每个线程生成不同的字符串ID。显然,使用类似于以下内容的内容将不会是线程安全的,因为多个线程将使用相同的
字典
,并扰乱其状态:

private static readonly Dictionary<string, uint> MyTallies = new Dictionary<string, uint>();

锁定对词典的访问权限。这样,这些方法就不再是多线程的了——一个方法中只有一个线程。查找lock语句

如果您更喜欢,请使用手动锁定-如果大多数访问是只读的,则多个读卡器单个写入器可能会提高性能。它允许多个读卡器锁,但一次只能有一个写卡器

3根本不是一个解决方案-因为字典不是线程安全的。除非您每次都使用ConcurrentDictionary或制作副本


1不是一个解决方案,因为它是一个架构更改。它可能会工作,但是为什么它首先是静态的呢?这是有原因的,您要求我们提供建议,但却没有适当的知识来提供建议。

这感觉就像您在进行预优化时冒着编写过于复杂代码的风险。我建议您编写最简单、最可靠的代码,直到您准确地测试性能瓶颈所在

除非确实需要,否则通常最好避免在线程之间共享对象或状态

使类非静态;每个线程都必须创建一个新实例, 并且可以为每个线程创建一个新字典。表演命中

这是我推荐的方式。对于一个字典来说,几个额外的字节是可以忽略的,而且可能会更快地使用,因为每个字典中的项目数量会更少

将字典传递给每个需要它的方法。然而 这会导致传入一个字典,只用于可选的 大部分时间不会使用的功能,因此它看起来像一个 调用代码必须做的奇怪的事情。还有性能冲击 因为调用代码每次都必须创建字典实例

我不能不看你的代码就知道,但感觉你的代码做得太多了。如果您考虑传入可能不使用的变量,那么您可能需要将代码分解成更小的组件。(见附件)


如果最终发现您确实需要在线程之间共享对象,那么您可以使用ConcurrentDictionary等多个类。(感谢Eldar Dordzhiev)

ConcurrentDictionary
?@EldarDordzhiev仅是退化边缘情况下的一种解决方案-任何不完全琐碎的东西都无法使用该解决方案,需要代码级锁定。不太确定用例是什么。你提到的选项意味着字典并不总是真正需要的。您能否显示一个示例用法,即谁负责清理字典,如何填充和使用字典。
internal static class HtmlFormatter {
    private static readonly Dictionary<string, uint> MyTallies = new Dictionary<string, uint>();

    internal static string RenderHtml(string markdown) {
        string outputHtml = "";

        // (process markdown and render to HTML)
        // (found a heading that requires a unique ID)
        var id = generatedId;
        string unique = "";
        if (MyTallies.ContainsKey(id)) {
            // Already exists; suffix "-x" where x is count of duplicate IDs
            unique = "-" + ++MyTallies[id];
        }
        else {
            MyTallies[id] = 0;
        }
        id += unique;

        // (append id string to HTML output and continue processing)

        return outputHtml;
    }
}