C# List 并发丢数据问题原因及解决方案
作者:丹枫无迹 发布时间:2023-06-18 17:53:54
标签:c#,list,并发
项目中出了个 BUG,就在我眼皮子底下,很明显的一个 BUG,愣是看了两天才看出来。
我有多个任务并发,任务执行完成后都有一个返回结果,我用一个 List
将结果收集起来,等所有任务完成后,发送出去。结果一直 丢数据。
我反复检查逻辑都没有问题,最后恍然 List
是非线程安全的。
大家都知道 List
是非线程安全的,但是如果仅有 Add
操作呢?估计有些人就会认为没问题。
下面的代码,期望输出的结果是 1000,然而,注释掉 lock
后,结果就不一样了。
class Program
{
static List<Person> persons;
static void Main(string[] args)
{
persons = new List<Person>();
object sync = new object();
Parallel.For(0, 1000, (i) =>
{
Person person = new Person
{
ID = i,
Name = "name" + i
};
lock (sync)
persons.Add(person);
});
Console.WriteLine(persons.Count);
Console.ReadLine();
}
class Person
{
public int ID { get; set; }
public string Name { get; set; }
}
}
利用安全集合ConcurrentBag取代list
测试程序
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyConcurrent
{
class Program
{
/// <summary>
/// ConcurrentBag并发安全集合
/// </summary>
public static void ConcurrentBagWithPallel()
{
ConcurrentBag<int> list = new ConcurrentBag<int>();
Parallel.For(0, 10000, item =>
{
list.Add(item);
});
Console.WriteLine("ConcurrentBag's count is {0}", list.Count());
int n = 0;
foreach (int i in list)
{
if (n > 10)
break;
n++;
Console.WriteLine("Item[{0}] = {1}", n, i);
}
Console.WriteLine("ConcurrentBag's max item is {0}", list.Max());
}
/// <summary>
/// 函数入口
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.WriteLine("ConcurrentBagWithPallel is runing" );
ConcurrentBagWithPallel();
Console.Read();
}
来源:https://www.cnblogs.com/gl1573/p/14392108.html


猜你喜欢
- 解决办法:1.VCS--->Enable Version Control Integration2.选择要关联的版本工具补充:git
- 本文实例讲述了Java判断两个日期相差天数的方法。分享给大家供大家参考。具体如下:import java.util.Calendar;pub
- 主要是应对这种需求:软件只允许启动一次。将这个问题转化一下,可以这样描述:对于一个软件,在启动一个进程之后,不允许启动其它进程,如果第二次打
- 本文实例讲述了Winform下实现图片切换特效的方法,是应用程序开发中非常实用的一个功能。分享给大家供大家参考之用。具体方法如下:本实例源自
- 本文实例讲述了C#中图片、二进制与字符串的相互转换方法。分享给大家供大家参考,具体如下:protected void Button1_Cli
- Java执行hadoop的基本操作实例代码向HDFS上传本地文件public static void uploadInputFile(Str
- weibo.java @Override &n
- Mybatis多层嵌套查询三张表:user article blog表的存储sql文件/*Navicat MySQL Data Transf
- 试题描述:一个球场C的球迷看台可容纳M*N个球迷。官方想统计一共有多少球迷群体,最大的球迷群体有多少人。球迷选座特性:同球迷群体会选择相邻座
- 本文实例为大家分享了java文件读写工具类的具体代码,供大家参考,具体内容如下import java.io.BufferedInputStr
- 一、重载(Overload)重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有
- 今天,简单讲讲android里如何获取一个视频文件的第一帧作为缩略图显示在界面上。之前,我说个最近需要从服务器下载视频文件,但是下载后肯定需
- 流程图 * vs过滤器 * 是SpringMVC的技术过滤器的Servlet的技术先过过滤器,过滤器过完才到DispatcherServle
- 1、springboot controller 单例Spring中 controller默认是单例的,因为单例所以不是线程安全的。所以需要注
- 引言RecyclerView是在Android5.0版本作为support-v7的一个组件出现,高效替代了最初的ListView等列表组件。
- 本文实例为大家分享了flutter日期时间选择器的具体代码,供大家参考,具体内容如下1 日期选择器 //设置默认显示的日期为当前 DateT
- fastjson转换对象实体@JsonProperty不生效项目场景请求第三方应用 返回json数据问题描述第三方返回的数据中,存在java
- 协程源码的结构在研究Kotlin源码之前,得先搞懂Kotlin源码结构分布。不然找不到该看哪里的代码。看源码之前当然先得有一个目标,最好是带
- java生成json时产生栈溢出错误环境java + hibernate +html本来,java中使用json事件很正常的事,但小心有的地
- 使用NOPI导入Excel文档NOPI版本:2.3.0,依赖于NPOI的SharpZipLib版本:0.86,经测试适用于.net4.0+记