ConcurrentBag的正确用法是什么? [英] What is the correct usage of ConcurrentBag?

查看:1223
本文介绍了ConcurrentBag的正确用法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在这里阅读了有关ConcurrentBag的先前问题,但是没有找到实现多线程的实际示例.

I've already read previous questions here about ConcurrentBag but did not find an actual sample of implementation in multi-threading.

ConcurrentBag是线程安全的包实现,针对同一线程将同时产生和使用存储在包中的数据的场景进行了优化."

ConcurrentBag is a thread-safe bag implementation, optimized for scenarios where the same thread will be both producing and consuming data stored in the bag."

当前,这是我代码中的当前用法(这简化为非实际代码):

Currently this is the current usage in my code (this is simplified not actual codes):

private void MyMethod()
{
    List<Product> products = GetAllProducts(); // Get list of products
    ConcurrentBag<Product> myBag = new ConcurrentBag<Product>();

    //products were simply added here in the ConcurrentBag to simplify the code
    //actual code process each product before adding in the bag
    Parallel.ForEach(
                products,
                new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
                product => myBag.Add(product));

    ProcessBag(myBag); // method to process each items in the concurrentbag
}

我的问题:
这是ConcurrentBag的正确用法吗?在这种情况下可以使用ConcurrentBag吗?

My questions:
Is this the right usage of ConcurrentBag? Is it ok to use ConcurrentBag in this kind of scenario?

对我来说,我认为简单的List<Product>和手动锁定会更好.原因是上述情况已经破坏了"同一线程将同时产生和使用存储在包中的数据"规则.
我还发现在并行操作中在每个线程中创建的ThreadLocal存储在操作后仍将存在(即使重新使用该线程对吗?),这可能会导致不希望的内存泄漏.
我对这个家伙说的对吗?还是简单的清除或清空方法来删除ConcurrentBag中的项目就足够了?

For me I think a simple List<Product> and a manual lock will do better. The reason for this is that the scenario above already breaks the "same thread will be both producing and consuming data stored in the bag" rule.
Also I also found out that the ThreadLocal storage created in each thread in the parallel will still exist after the operation (even if the thread is reused is this right?) which may cause an undesired memory leak.
Am I right in this one guys? Or a simple clear or empty method to remove the items in the ConcurrentBag is enough?

推荐答案

这似乎可以很好地使用ConcurrentBag.线程局部变量是该包的成员,并且将在该包同时获得垃圾回收的资格(清除内容不会释放它们).没错,一个带有锁的简单列表就可以满足您的情况.如果您在循环中所做的工作非常重要,那么线程同步的类型对整体性能将无济于事.在这种情况下,您可能会更习惯使用自己熟悉的内容.

This looks like an ok use of ConcurrentBag. The thread local variables are members of the bag, and will become eligible for garbage collection at the same time the bag is (clearing the contents won't release them). You are right that a simple List with a lock would suffice for your case. If the work you are doing in the loop is at all significant, the type of thread synchronization won't matter much to the overall performance. In that case, you might be more comfortable using what you are familiar with.

另一种选择是使用 ParallelEnumerable.Select ,它与您要尝试的内容相匹配做得更紧密.同样,您将看到的任何性能差异都可以忽略不计,并且坚持使用您所知道的东西也没有错.

Another option would be to use ParallelEnumerable.Select, which matches what you are trying to do more closely. Again, any performance difference you are going to see is likely going to be negligible and there's nothing wrong with sticking with what you know.

一如既往,如果这种方法的性能至关重要,那么就没有替代品可以尝试和测量.

As always, if the performance of this is critical there's no substitute for trying it and measuring.

这篇关于ConcurrentBag的正确用法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆