C# ConcurrentBag的字符串和使用.Contains in Parallel.ForEach
我使用ConcurrentBag来包含字符串列表。有时它会包含一个副本 但是,我会在添加新条目之前检查它的内容,这样它就不会有重复的条目C# ConcurrentBag的字符串和使用.Contains in Parallel.ForEach,c#,multithreading,concurrency,parallel-processing,thread-safety,C#,Multithreading,Concurrency,Parallel Processing,Thread Safety,我使用ConcurrentBag来包含字符串列表。有时它会包含一个副本 但是,我会在添加新条目之前检查它的内容,这样它就不会有重复的条目 ConcurrentDictionary<string, string> SystemFiles = PopulateSystemFiles(); ConcurrentBag<string> SystemNames = new ConcurrentBag<string>(); Parallel.ForEach(System
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);
}
});
ConcurrentDictionary SystemFiles=PopulateSystemFiles();
ConcurrentBag SystemNames=新的ConcurrentBag();
Parallel.ForEach(系统文件,文件=>
{
字符串名称=GetSystemName(file.Value);
如果(!SystemNames.Contains(name))
{
SystemNames.Add(name);
}
});
我的假设是.Contains方法不是线程安全的。我说的对吗?
ConcurrentBag
是线程安全的,但您的代码不是:
if (!SystemNames.Contains(name))
{
SystemNames.Add(name);
}
Contains
将以线程安全的方式执行,然后Add
也将以线程安全的方式执行,但您不能保证在两者之间没有添加项目
根据您的需要,我建议您改用ConcurrentDictionary
。忽略该值,因为您不需要它
var SystemNames = new ConcurrentDictionary<string, bool>();
ConcurrentBag
是线程安全的,但您的代码不是:
if (!SystemNames.Contains(name))
{
SystemNames.Add(name);
}
Contains
将以线程安全的方式执行,然后Add
也将以线程安全的方式执行,但您不能保证在两者之间没有添加项目
根据您的需要,我建议您改用ConcurrentDictionary
。忽略该值,因为您不需要它
var SystemNames = new ConcurrentDictionary<string, bool>();
难道你不能全部添加并调用Distinct()函数吗?枚举ConcurrentBag效率极低。改用ConcurrentDictionary集合是线程安全的,如“同时使用它不会损坏其状态”。它不会使你的“包含然后添加”操作原子化。你的代码不是线程安全的,是的。但如果使用锁,则可以使用非线程安全的集合,如HashSet。最后,我认为你应该用一个ConcurrentDictionary来替换你的ConcurrentBag(这有点尴尬,因为你将只使用键,而不是值,但这很好)@CathalMF ConcurrentDictionary有一个TryAdd方法,它以原子的方式执行“if not contains then add”操作。你不能全部添加并调用Distinct()吗函数?枚举ConcurrentBag效率极低。改用ConcurrentDictionary集合是线程安全的,如“同时使用它不会损坏其状态”。它不会使你的“包含然后添加”操作原子化。你的代码不是线程安全的,是的。但如果使用锁,则可以使用非线程安全的集合,如HashSet。最后,我认为您应该用ConcurrentDictionary替换ConcurrentBag(这有点尴尬,因为您将只使用键,而不是值,但这很好)@CathalMF ConcurrentDictionary有一个TryAdd方法,它以原子方式执行“if not contains then add”操作