Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ConcurrentBag的字符串和使用.Contains in Parallel.ForEach_C#_Multithreading_Concurrency_Parallel Processing_Thread Safety - Fatal编程技术网

C# ConcurrentBag的字符串和使用.Contains in Parallel.ForEach

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

我使用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);
    }
});
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”操作