我使用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方法不是线程安全的。我说得对吗?
答案 0 :(得分:3)
ConcurrentBag
是线程安全的,但您的代码却不是:
if (!SystemNames.Contains(name))
{
SystemNames.Add(name);
}
Contains
将以线程安全的方式执行,然后Add
也将以线程安全的方式执行,但是您不能保证没有在两者之间添加任何项。
根据您的需要,我建议改用ConcurrentDictionary
。只需忽略不需要的值即可。
var SystemNames = new ConcurrentDictionary<string, bool>();
然后使用TryAdd
方法在单个原子操作中执行“如果不包含则添加”:
SystemNames.TryAdd(name, true);