Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

PLinq and source IEnumerable thread safety

0.00/5 (No votes)
3 Sep 2012 1  
PLinq and source IEnumerable thread safety

As I discovered that the source IEnumerable is called by PLINQ from multiple threads, it made me thinking: how can it possibly work? E.g. when someone writes code like this:

Enumerable.Range(1,1000).AsParallel()...

the Range iterator must keep its current state in some variable. If this state is accessed from multiple threads, how are race conditions avoided? Here are my findings in order:

1. Enumerable.Range() returns an IEnumerable<int>. This enumerable’s GetEnumerator() will return different enumerators for different threads. This appears to be a built-in feature of enumerables generated from yield return keyword. Reflector is my witness. Proof link.

Each enumerator, however, is not thread safe and does not have any locking code.

2. AsParallel() calls GetEnumerator() only once, and then uses it from multiple threads, so the above protection does not work.

3. Stephen Toub of Microsoft says, that as IEnumerable is inherently thread unsafe, PLINQ has locking built in.

4. As per Reflector it appears to be implemented in the PartitionedDataSoruce<T>.MoveNext() method.

So, relax folks. Your enumerator can and will be thread unsafe, PLINQ has its own locks to take care of that.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here