【发布时间】:2019-02-20 17:01:23
【问题描述】:
我使用 ConcurrentBag 来包含一个字符串列表。有时它会包含一个副本。
但是我在添加新条目之前检查了它的内容,所以它不应该有重复。
ConcurrentDictionary<string, string> SystemFiles = PopulateSystemFiles();
ConcurrentBag<string> SystemNames = new ConcurrentBag<string>();
Parallel.ForEach(SystemFiles, file =>
{
string name = GetSystemName(file.Value);
if (!SystemNames.Contains(name))
{
SystemNames.Add(name);
}
});
我的假设是 .Contains 方法不是线程安全的。我说的对吗?
【问题讨论】:
-
你不能把它全部添加并调用一个 Distinct() 函数吗?
-
枚举 ConcurrentBag 效率极低。改用 ConcurrentDictionary
-
集合是线程安全的,就像“同时使用它不会破坏它的状态”。它不会使您的“包含然后添加”操作原子化。你的代码不是线程安全的
-
会的,是的。但是如果你使用锁,那么你可以使用非线程安全的集合,比如 HashSet。最后,我认为你应该用 ConcurrentDictionary 替换你的 ConcurrentBag (这有点尴尬,因为你将只使用键,而不是值,但没关系)
-
@CathalMF ConcurrentDictionary 有一个 TryAdd 方法,它以原子方式执行“如果不包含则添加”操作
标签: c# multithreading concurrency parallel-processing thread-safety