gpt4 book ai didi

c# - 似乎 ConcurrentBag 不是线程安全的

转载 作者:太空宇宙 更新时间:2023-11-03 17:38:29 27 4
gpt4 key购买 nike

我编写了一个程序,其中列表构建器方法返回 IEnumerable of string,其中包括大量字符串(100 万个项目),我将其存储在 List of string 中,然后它将所有项目附加到 中的 StringBuilder 实例中并行.Foreach。然后我打印了 stringBuilderInstance.Length

问题是它少于 1000000 。经过一些googling ,我意识到 List 集合不是线程安全的,这导致了这个问题。所以我想到了 2 个解决方案:

1) 使用

2) 使用ConcurrentBag

当我使用 lock 时,没问题,长度是 100 万,但是:

当我使用字符串的 ConcurrentBag 时,长度比我预期的要短!

这个问题的根本原因是什么?

列表创建器方法:

public static List<string> CreateList()
{
List<string> result = new List<string>();
for (int i = 0; i < 1000000; i++)
{
result.Add(1.ToString());
}
return result;
}

使用并发包:

public static void DoWithParallel_ThreadSafe()
{
ConcurrentBag<string> listOfString = new ConcurrentBag<string>(CreateList());
StringBuilder a = new StringBuilder();
Action<string> appender = (number) =>
{
a.Append(number);
};
Parallel.ForEach(listOfString, appender);
Console.WriteLine($"The string builder lenght : {a.Length}");
}

使用锁:

public static void DoWithParallel_UnsafeThread_Lock()
{
List<string> listOfString = CreateList();
StringBuilder a = new StringBuilder();
Action<string> appender = (number) =>
{
lock (listOfString)
{
a.Append(number);
}
};
Parallel.ForEach(listOfString, appender);
Console.WriteLine($"The string builder lenght : {a.Length}");
}

主要内容:

static void Main(string[] args)
{
DoWithParallel_UnsafeThread_Lock();
DoWithParallel_ThreadSafe();
Console.ReadKey();
}

提前谢谢你。

最佳答案

StringBuilder 不能从多线程中改变,因此当您尝试这样做时代码不起作用的原因。请注意,锁定是没有意义的;只是不要首先创建多个线程来完成工作,因为无法从多个线程完成工作。由于您永远不会从多个线程访问 ConcurrentBag,因此使用它而不是 List 毫无意义。

关于c# - 似乎 ConcurrentBag 不是线程安全的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45425006/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com