I am using the below code
var processed = new List<Guid>(); Parallel.ForEach(items, item => { processed.Add(SomeProcessingFunc(item)); });
Is the above code thread safe? Is there a chance of processed list getting corrupted? Or should i use a lock before adding?
var processed = new List<Guid>(); Parallel.ForEach(items, item => { lock(items.SyncRoot) processed.Add(SomeProcessingFunc(item)); });
thanks.
If a writer may be writing at the same time, List. Contains is definitely not thread safe. You'll need to wrap it and any other reads and writes with a lock.
In fact, by default, classes are not thread-safe. Being thread-safe would mean that any operation modifying the list would need to be interlocked against simultaneous access. This would be necessary even for those lists that will only ever be used by a single thread. That would be very inefficient.
Yes, List<T> is fine to read from multiple threads concurrently, so long as nothing's writing.
Yes, these are thread-safe. Stack, Vector, Properties and Hashtable classes have all been implemented in Java 1.0, therefore they are mostly considered to be legacy classes.
No! It is not safe at all, because processed.Add
is not. You can do following:
items.AsParallel().Select(item => SomeProcessingFunc(item)).ToList();
Keep in mind that Parallel.ForEach
was created mostly for imperative operations for each element of sequence. What you do is map: project each value of sequence. That is what Select
was created for. AsParallel
scales it across threads in most efficient manner.
This code works correctly:
var processed = new List<Guid>(); Parallel.ForEach(items, item => { lock(items.SyncRoot) processed.Add(SomeProcessingFunc(item)); });
but makes no sense in terms of multithreading. lock
ing at each iteration forces totally sequential execution, bunch of threads will be waiting for single thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With