Adding to a list in a Parallel.ForEach loop in a threadsafe manner

前端 未结 3 560
不知归路
不知归路 2020-12-06 01:28

I have a bit of code that works like this on a list of obj objects called ListofObjects:

List NewListofObjects();

Parall         


        
相关标签:
3条回答
  • 2020-12-06 02:02

    You can use the locking block like the following code to insert items into your list in a thread-safe manner.

    var sync = new object();
    var myNewList = new List<SomeObject>();
    Parallel.ForEach(myListOfSomethings, a =>
        {
            // Some other code...
            var someObj = new SomeObject();
            // More other code...
            lock(sync)
            {
                myNewList.Add(someObj);
            }
            // Even more code...
        });
    
    0 讨论(0)
  • 2020-12-06 02:12

    Is this because my NewListofObjects.Add(newobj) method is not threadsafe?

    Correct. It is not threadsafe.

    Any instance members are not guaranteed to be thread safe.

    That's from MSDN referring to List<T> (scroll to the section titled "Thread Safety").

    If so, how can I make it threadsafe?

    Use a concurrent collection, like ConcurrentBag<T>. Note that you lose the ability to keep track of the order that items were inserted.

    0 讨论(0)
  • 2020-12-06 02:14

    The .NET Framework 4 introduces the System.Collections.Concurrent namespace, which includes several collection classes that are both thread-safe and scalable. https://docs.microsoft.com/en-us/dotnet/standard/collections/thread-safe/

    BlockingCollection<int>[] sourceArrays = new BlockingCollection<int>[5];
    for (int i = 0; i < sourceArrays.Length; i++)
        sourceArrays[i] = new BlockingCollection<int>(500);
    Parallel.For(0, sourceArrays.Length * 500, (j) =>
    {
        int k = BlockingCollection<int>.TryAddToAny(sourceArrays, j);
        if (k >= 0)
            Console.WriteLine("added {0} to source data", j);
    });
    
    0 讨论(0)
提交回复
热议问题