线程安全集合ConcurrentBag 添加和删除项目

2022-02-28  乐帮网

c#

表示对象的线程安全的无序集合,下面以.Net6为例进行介绍。可使用 ConcurrentBag<T> 类。下面的示例演示如何在中添加和移除项 ConcurrentBag<T> ,请注意它是一个无序集合,并不能移除特定对象。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;

class ConcurrentBagDemo
{
    // Demonstrates:
    //      ConcurrentBag<T>.Add()
    //      ConcurrentBag<T>.IsEmpty
    //      ConcurrentBag<T>.TryTake()
    //      ConcurrentBag<T>.TryPeek()
    static void Main()
    {
        // Add to ConcurrentBag concurrently
        ConcurrentBag<int> cb = new ConcurrentBag<int>();
        List<Task> bagAddTasks = new List<Task>();
        for (int i = 0; i < 500; i++)
        {
            var numberToAdd = i;
            bagAddTasks.Add(Task.Run(() => cb.Add(numberToAdd)));
        }

        // Wait for all tasks to complete
        Task.WaitAll(bagAddTasks.ToArray());

        // Consume the items in the bag
        List<Task> bagConsumeTasks = new List<Task>();
        int itemsInBag = 0;
        while (!cb.IsEmpty)
        {
            bagConsumeTasks.Add(Task.Run(() =>
            {
                int item;
                if (cb.TryTake(out item))
                {
                    Console.WriteLine(item);
                    itemsInBag++;
                }
            }));
        }
        Task.WaitAll(bagConsumeTasks.ToArray());

        Console.WriteLine($"There were {itemsInBag} items in the bag");

        // Checks the bag for an item
        // The bag should be empty and this should not print anything
        int unexpectedItem;
        if (cb.TryPeek(out unexpectedItem))
            Console.WriteLine("Found an item in the bag when it should be empty");
    }
}

可以看到它非常适合无序队列这种情况。重点特征是高并发和无序。当数据量瞬间大但是总量可控时也可以选择它。例如我的一段改造代码在使用过程中表现的就非常好。

ConcurrentBag<ObstacleCounter> _counter = new ConcurrentBag<ObstacleCounter>();
 List<ObstacleCounter> crlist = new List<ObstacleCounter>();
            while (!_counter.IsEmpty)
            {
                ObstacleCounter cr;
                if (_counter.TryTake(out cr))
                {
                    if (cr.Milliseconds < 1000)
                    {
                        crlist.Add(cr);
                    }
                }
            }
            foreach (var c in crlist)
            {
                _counter.Add(c);
            }

https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.concurrent.concurrentbag-1?view=net-6.0

公众号二维码

关注我的微信公众号
在公众号里留言交流
投稿邮箱:1052839972@qq.com

庭院深深深几许?杨柳堆烟,帘幕无重数。
玉勒雕鞍游冶处,楼高不见章台路。
雨横风狂三月暮。门掩黄昏,无计留春住。
泪眼问花花不语,乱红飞过秋千去。

欧阳修

付款二维码

如果感觉对您有帮助
欢迎向作者提供捐赠
这将是创作的最大动力