软件编程
位置:首页>> 软件编程>> C#编程>> C# List 并发丢数据问题原因及解决方案

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com