Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel features in .Net 4.0

I have been going over the practicality of some of the new parallel features in .Net 4.0.

Say I have code like so:

foreach (var item in myEnumerable)
    myDatabase.Insert(item.ConvertToDatabase());

Imagine myDatabase.Insert is performing some work to insert to a SQL database.

Theoretically you could write:

Parallel.ForEach(myEnumerable, item => myDatabase.Insert(item.ConvertToDatabase()));

And automatically you get code that takes advantage of multiple cores.

But what if myEnumerable can only be interacted with by a single thread? Will the Parallel class enumerate by a single thread and only dispatch the result to worker threads in the loop?

What if myDatabase can only be interacted with by a single thread? It would certainly not be better to make a database connection per iteration of the loop.

Finally, what if my "var item" happens to be a UserControl or something that must be interacted with on the UI thread?

What design pattern should I follow to solve these problems?

It's looking to me that switching over to Parallel/PLinq/etc is not exactly easy when you are dealing with real-world applications.

like image 687
jonathanpeppers Avatar asked May 05 '10 18:05

jonathanpeppers


1 Answers

The IEnumerable<T> interface is inherently not thread safe. Parallel.ForEach will automatically handle this, and only parallelize the items coming out of your enumeration. (The sequence will always be traversed, one element at a time, in order - but the resulting objects get parallelized.)

If your classes (ie: the T) cannot be handled by multiple threads, then you should not try to parallelize this routine. Not every sequence is a candidate for parallelization - which is one reason why this isn't done automatically by the compiler ;)

If you're doing work which requires working with the UI thread, this is still potentially possible. However, you'll need to take the same care you would anytime you're dealing with user interface elements on background threads, and marshal the data back onto the UI thread. This can be simplified in many cases using the new TaskScheduler.FromCurrentSynchronizationContext API. I wrote about this scenario on my blog here.

like image 177
Reed Copsey Avatar answered Oct 19 '22 09:10

Reed Copsey