C# List 并发丢数据问题原因及解决方案

 更新时间:2021年02月20日 08:41:35   作者:丹枫无迹  
这篇文章主要介绍了C# List 并发丢数据问题原因及解决方案,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下

项目中出了个 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();
    }

以上就是C# List 并发丢数据问题原因及解决方案的详细内容,更多关于C# List 并发丢数据的资料请关注脚本之家其它相关文章!

相关文章

  • c#网络唤醒功能实现

    c#网络唤醒功能实现

    网络唤醒实现了对网络的集中管理,即在任何时刻,网管中心的IT管理人员可以经由网络远程唤醒一台处于休眠或关机状态的计算机,下面使用c#实现网络唤醒功能
    2014-01-01
  • Unity实现虚拟摇杆效果

    Unity实现虚拟摇杆效果

    这篇文章主要为大家详细介绍了Unity实现虚拟摇杆效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#针对xml文件转化Dictionary的方法

    C#针对xml文件转化Dictionary的方法

    这篇文章主要介绍了C#针对xml文件转化Dictionary的方法,是C#操作XML文件的典型应用,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • C#异常处理总结及简单实例

    C#异常处理总结及简单实例

    这篇文章主要介绍了C#异常处理总结及简单实例的相关资料,需要的朋友可以参考下
    2017-06-06
  • winform壁纸工具为图片添加当前月的日历信息

    winform壁纸工具为图片添加当前月的日历信息

    使用用winform做了一个设置壁纸小工具,为图片添加当月的日历并设为壁纸,可以手动/定时设置壁纸,最主要的特点是在图片上生成当前月的日历信息,感兴趣的你可以参考下
    2013-03-03
  • C#文件读写操作详细操作指南

    C#文件读写操作详细操作指南

    这篇文章主要给大家介绍了关于C#文件读写操作详细操作指南,在后端开发中使用C#语言进行文件操作是一个常见的任务,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • 10分钟学会VS NuGet包私有化部署

    10分钟学会VS NuGet包私有化部署

    本文主要介绍了10分钟学会VS NuGet包私有化部署,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • C#中out与ref作用区别示例分析

    C#中out与ref作用区别示例分析

    这篇文章主要为大家介绍了C#中out与ref作用区别示例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 详解C# partial 关键字的使用

    详解C# partial 关键字的使用

    局部类型允许我们将一个类、结构或接口分成几个部分,分别实现在几个不同的.cs文件中。接下来通过本文给大家分享C# partial 关键字的使用,感兴趣的的朋友一起看看吧
    2017-08-08
  • C#同步、异步远程下载文件实例

    C#同步、异步远程下载文件实例

    使用C#下载一个Internet上的文件主要是依靠HttpWebRequest/HttpWebResonse和WebClient。具体处理起来还有同步和异步两种方式,所以我们其实有四种组合
    2014-04-04

最新评论