简体   繁体   中英

Processing a ConcurrentBag shows over 5000 tasks when only 2 items in bag

Found the following ConcurrentBag example on Microsoft here .

I was debugging a unit test and kind of inspecting around and the bagConsumeTasks had over 5000 items in it. Is this normal? The bag had only 2 itmes.

在此处输入图片说明

HashSet<string> x = new HashSet<string>();
List<Task> bagConsumeTasks = new List<Task>();
int itemsInBag = 0;
while (!result.IsEmpty)
{
    bagConsumeTasks.Add(Task.Run(() =>
    {
        string item;
        if (result.TryTake(out item))
        {
            x.Add(item);
            itemsInBag++;
        }
    }));
}
Task.WaitAll(bagConsumeTasks.ToArray());

There's a race between checking result.IsEmpty and the tasks consuming items, leading the code to start more tasks than needed.

The increment of local variable itemsInBag by many tasks in parallel is also a race, but mitigated by the call to Console.WriteLine just before it.

While in some cases this could be a bug, I guess the over-scheduling of tasks may be deliberate here, to demonstrate the class running under high contention?

Because nothing else is using the concurrent bag, the example could just create a fixed number of Tasks:

    List<Task> bagConsumeTasks = new List<Task>();
    int itemsInBag = 0;
    for (int i = 0; i < 500; i++)
    {
        bagConsumeTasks.Add(Task.Run(() =>
        {
            int item;
            if (cb.TryTake(out item))
            {
                Console.WriteLine(item);
                Interlocked.Increment(ref itemsInBag);
            }
        }));
    }
    Task.WaitAll(bagConsumeTasks.ToArray());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM