到目前为止,我一直在 C# 库中开发一个静态类
,所有方法显然都是静态的。任何被操作的数据都会被传入,所以这是线程安全的。但是,我正在实现一项功能,该功能需要 Dictionary
来统计某些字符串 ID,这些字符串 ID 将为每个线程生成不同的 ID。显然使用类似下面的东西将不是线程安全的,因为多个线程将使用相同的 Dictionary
并弄乱它的状态:
private static readonly Dictionary<string, uint> MyTallies = new Dictionary<string, uint>();
那么让这个线程安全的最佳选择是什么?在我看来,有 3 个(有点不好)选项:
- 使类成为非静态的;每个线程都必须创建一个新实例,并且可以为每个线程创建一个新的
Dictionary
。性能受到影响。 - 使用
Dictionary
在代码周围放置一个锁
,并在锁的末尾清除Dictionary
。性能受到很大影响。 - 将
Dictionary
传递给每个需要它的方法。然而,这会导致Dictionary
只是为了一个大多数时候不会使用的可选功能而被传递,因此调用代码必须做的事情似乎很奇怪。由于调用代码每次都必须创建Dictionary
实例,因此性能也会受到影响。
那么我最好的选择是什么,还是有其他我没有想到的更好的选择?
编辑:一个简单的用例:
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;
}
}
最佳答案
锁定对字典的访问。这样,方法就不再是多线程的了——方法中只会有一个。查找锁定语句。
如果您更喜欢,请使用手动锁 - 如果大多数访问是只读的,则多个读取器单个写入器可能会提高性能。它允许多个读者锁定,但一次只能锁定一个作者。
3 根本不是解决方案——因为字典不是线程安全的。除非你每次都使用 ConcurrentDictionary 或复制一份。
1 不是解决方案,因为它是架构更改。它可能有效 - 但为什么它首先是静态的?这是有原因的,您要求我们在没有适当知识的情况下提供建议。
关于c# - 使静态类中的字典成为线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35440356/