我正在使用 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 方法不是线程安全的。我说得对吗?
最佳答案
ConcurrentBag
是线程安全的,但您的代码不是:
if (!SystemNames.Contains(name))
{
SystemNames.Add(name);
}
Contains
将以线程安全的方式执行,然后 Add
也将以线程安全的方式执行,但您不能保证某个项目没有中间添加了。
根据您的需要,我建议改用 ConcurrentDictionary
。忽略该值,因为您不需要它。
var SystemNames = new ConcurrentDictionary<string, bool>();
然后使用 TryAdd
方法在单个原子操作中执行“如果不包含则添加”:
SystemNames.TryAdd(name, true);
关于c# - ConcurrentBag 字符串并在 Parallel.ForEach 中使用 .Contains,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54791721/