How to remove a single, specific object from a ConcurrentBag<>?

后端 未结 9 499
误落风尘
误落风尘 2021-02-02 04:34

With the new ConcurrentBag in .NET 4, how do you remove a certain, specific object from it when only TryTake() and TryPeek() are

相关标签:
9条回答
  • 2021-02-02 05:24
    public static void Remove<T>(this ConcurrentBag<T> bag, T item)
    {
        while (bag.Count > 0)
        {
            T result;
            bag.TryTake(out result);
    
            if (result.Equals(item))
            {
                break; 
            }
    
            bag.Add(result);
        }
    
    }
    
    0 讨论(0)
  • 2021-02-02 05:25

    The ConcurrentBag is great to handle a List where you can add items and enumerate from many thread, then eventually throw it away as its name is suggesting :)

    As Mark Byers told, you can re-build a new ConcurrentBag that does not contains the item you wish to remove, but you have to protect this against multiple threads hits using a lock. This is a one-liner:

    myBag = new ConcurrentBag<Entry>(myBag.Except(new[] { removedEntry }));
    

    This works, and match the spirit in which the ConcurrentBag has been designed for.

    0 讨论(0)
  • 2021-02-02 05:26

    This is my extension class which I am using in my projects. It can a remove single item from ConcurrentBag and can also remove list of items from bag

    public static class ConcurrentBag
    {
        static Object locker = new object();
    
        public static void Clear<T>(this ConcurrentBag<T> bag)
        {
            bag = new ConcurrentBag<T>();
        }
    
    
        public static void Remove<T>(this ConcurrentBag<T> bag, List<T> itemlist)
        {
            try
            {
                lock (locker)
                {
                    List<T> removelist = bag.ToList();
    
                    Parallel.ForEach(itemlist, currentitem => {
                        removelist.Remove(currentitem);
                    });
    
                    bag = new ConcurrentBag<T>();
    
    
                    Parallel.ForEach(removelist, currentitem =>
                    {
                        bag.Add(currentitem);
                    });
                }
    
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
    
        public static void Remove<T>(this ConcurrentBag<T> bag, T removeitem)
        {
            try
            {
                lock (locker)
                {
                    List<T> removelist = bag.ToList();
                    removelist.Remove(removeitem);                
    
                    bag = new ConcurrentBag<T>();
    
                    Parallel.ForEach(removelist, currentitem =>
                    {
                        bag.Add(currentitem);
                    });
                }
    
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题