服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C# List 并发丢数据问题原因及解决方案

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

2022-11-02 10:54丹枫无迹 C#

这篇文章主要介绍了C# List 并发丢数据问题原因及解决方案,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下

项目中出了个 BUG,就在我眼皮子底下,很明显的一个 BUG,愣是看了两天才看出来。

我有多个任务并发,任务执行完成后都有一个返回结果,我用一个 List 将结果收集起来,等所有任务完成后,发送出去。结果一直 丢数据。

我反复检查逻辑都没有问题,最后恍然 List 是非线程安全的。

大家都知道 List 是非线程安全的,但是如果仅有 Add 操作呢?估计有些人就会认为没问题。

下面的代码,期望输出的结果是 1000,然而,注释掉 lock 后,结果就不一样了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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

测试程序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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 并发丢数据的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/gl1573/p/14392108.html

延伸 · 阅读

精彩推荐
  • C#Unity实现已知落点和速度自动计算发射角度

    Unity实现已知落点和速度自动计算发射角度

    这篇文章主要为大家详细介绍了Unity实现已知落点和速度自动计算发射角度,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以...

    10152022-08-24
  • C#基于C#对用户密码使用MD5加密与解密

    基于C#对用户密码使用MD5加密与解密

    C#中常涉及到对用户密码的加密于解密的算法,其中使用MD5加密是最常见的的实现方式。本文总结了通用的算法并结合了自己的一点小经验,分享给大家...

    Healer00711122021-11-05
  • C#C#编程实现发送邮件的方法(可添加附件)

    C#编程实现发送邮件的方法(可添加附件)

    这篇文章主要介绍了C#编程实现发送邮件的方法,具备添加附件的功能,涉及C#文件传输及邮件发送的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    期待秋天的叶9002021-11-05
  • C#C#实现集合转换成json格式数据的方法

    C#实现集合转换成json格式数据的方法

    这篇文章主要介绍了C#实现集合转换成json格式数据的方法,涉及C#针对dataTable、Enumerable及Json格式数据的遍历及转换操作相关技巧,需要的朋友可以参考下...

    ajunfly9542021-12-01
  • C#C# WinForm调用Shell_NotifyIcon的示例代码

    C# WinForm调用Shell_NotifyIcon的示例代码

    这篇文章主要介绍了C# WinForm调用Shell_NotifyIcon的示例代码,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...

    正在缓冲9592022-10-17
  • C#Unity Shader实现新手引导遮罩镂空效果

    Unity Shader实现新手引导遮罩镂空效果

    这篇文章主要为大家详细介绍了Unity Shader实现新手引导遮罩镂空效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一...

    mac_zly4022022-08-27
  • C#C#编程和Visual Studio使用技巧(上)

    C#编程和Visual Studio使用技巧(上)

    C#是一门伟大的编程语言,与C++和Java相比,它的语法更简单,相对来说更好入门。Visual Studio作为.Net平台上最重量级的IDE,也通过不断的更新为开发者带来...

    C#教程网9652021-10-29
  • C#C#中查找Dictionary中的重复值的方法

    C#中查找Dictionary中的重复值的方法

    这篇文章主要介绍了C#中查找Dictionary中的重复值的方法,需要的朋友可以参考下...

    divor8742021-10-25