RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 854117
Accepted
Adam Shakhabov
Adam Shakhabov
Asked:2020-07-13 17:55:33 +0000 UTC2020-07-13 17:55:33 +0000 UTC 2020-07-13 17:55:33 +0000 UTC

ConcurrentBag<T> 和 List<T> 的区别

  • 772

我试图了解集合ConcurrentBag<T>和List<T>本文之间的区别。

出于某种原因,在我看来,如果我使用List<T>它并且当一个线程在那里写一些东西并尝试对另一个线程做同样的事情时,会弹出一个异常,但不,一切正常。


我的剧本

有一种多线程处理场景,在其工作结束时,所有线程必须将其结果写入一个集合:

class Program
{
    static void Main(string[] args)
    {
        var results = new List<string>();
        //var results = new ConcurrentBag<string>();

        // STEP 1: Get results.
        Parallel.For(1, 50000, idx =>
        {
            // Some process.
            //...
            results.Add("something");
        });

        // STEP 2: Process results.
        foreach (var result in results)
        {
            //...
        }
    }
}

问题

ConcurrentBag<T>我在用例中而不是List<T>在我的案例中获得什么优势?

还有一个小问题:results称它为共享资源是否正确?

c#
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    tym32167
    2020-07-13T18:19:11Z2020-07-13T18:19:11Z

    出于某种原因,在我看来,如果我使用 List 并且当一个线程在那里写一些东西并尝试对另一个线程做同样的事情时,会弹出一个异常

    问题可能会发生,也可能不会发生。这被称为线程不安全集合 - 当问题可能出现时。今天它工作,明天它会下降 - 因为不能保证在并行工作时,2个线程不会尝试同时写入列表。

    您有一个列表的事实Parallel.For并不能保证并行访问。并发访问是指 2 个或更多线程尝试在同一时间单位内对列表进行操作。在您的情况下,在第一次、第二次、第三次启动期间,这可能不会发生,但在第 99 次启动时,代码会下降。

    多线程处理

    多线程

    在使用 ConcurrentBag 而不是 List 的情况下我有什么优势

    如果您选择,ConcurrentBag<T>您将获得保证您的代码不会在多线程工作中崩溃。使用时List<T>没有任何保证,甚至不能保证不会丢失数据,也不能保证不会出现异常。我再说一遍——即使是相同的多线程代码也可以在 99 种情况下工作,并且在使用线程不安全的集合时会在 1 种情况下崩溃。

    结果,将其称为共享资源是否正确?

    既然线程共享它,那么是的

    在您的具体代码中,我个人不认为共享资源有什么意义,这样写要容易得多:

    var results = Enumerable
            .Range(1, 50000)
            .AsParallel()
            .Select(x=> /*....*/)
            .ToList();
    
    foreach (var result in results)
    {
        //...
    }
    
    • 6
  2. user177221
    2020-07-13T18:20:52Z2020-07-13T18:20:52Z

    出于某种原因,在我看来,如果我使用 List 并且当一个线程在那里写一些东西并尝试对另一个线程做同样的事情时,会弹出一个异常,但不,一切正常。

    List<T>不是线程安全的。这意味着当从不同的线程访问数据时,它根本不采取任何措施来保护数据。没有锁,甚至没有并发检查。

    你不会得到例外,但你也不会得到数据完整性保证。利用ConcurrentBag<T>

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5