I have a bit of code that works like this on a list of obj objects called ListofObjects:
List NewListofObjects();
Parall
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...
});
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.
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);
});