PLINQ (Parallel Linq) is just a new way to write regular Linq queries so that they run in parallel - in other words, Framework will automatically take care of running your query in multiple threads, that they will end faster (i.e. use multiple processor cores).
For example, let's say that you have a bunch of lines, and you want to get all those that start with the letter "A". You can write your request as follows:
var words = new[] { "Apple", "Banana", "Coconut", "Anvil" }; var myWords = words.Select(s => s.StartsWith("A"));
And it works great. If you had 50,000 words to search for, you could take advantage of the fact that each test is independent, and divide it into several cores:
var myWords = words.AsParallel().Select(s => s.StartsWith("A"));
This is all you need to do to turn a regular query into a parallel one that runs on multiple cores. Pretty neat.
TPL (parallel task library) is a kind of addition to PLINQ, and together they make parallel extensions. While PLINQ is largely based on a functional programming style without side effects, side effects are exactly what TPL is for. If you want to actually work in parallel, and not just search / select things in parallel, you use TPL.
TPL is essentially a Parallel class that provides For , Foreach and Invoke overloads. Invoke bit like Queue tasks in ThreadPool , but a bit easier to use. IMO, the more interesting bits are For and Foreach . For example, let's say you have a whole bunch of files that you want to compress. You can write a regular serial version:
string[] fileNames = (...); foreach (string fileName in fileNames) { byte[] data = File.ReadAllBytes(fileName); byte[] compressedData = Compress(data); string outputFileName = Path.ChangeExtension(fileName, ".zip"); File.WriteAllBytes(outputFileName, compressedData); }
Again, each iteration of this compression is completely independent of any other. We can accelerate this by doing several of them at once:
Parallel.ForEach(fileNames, fileName => { byte[] data = File.ReadAllBytes(fileName); byte[] compressedData = Compress(data); string outputFileName = Path.ChangeExtension(fileName, ".zip"); File.WriteAllBytes(outputFileName, compressedData); });
And again, that is all that is required to parallelize this operation. Now, when we run our CompressFiles method (or as we call it), it will use several processor cores and will probably end in half or 1/4 times.
The advantage of this is that it just throws everything in ThreadPool , so that it actually runs synchronously. If you used ThreadPool instead (or just regular instances of Thread ), you will have to come up with a way to find out when all the tasks are completed, and although it is not very difficult, this is something that many people tend to enter, or at least have problems. When you use the Parallel class, you do not need to think about it; The multi-threaded aspect is hidden from you; all this is handled behind the scenes.
Reactive extensions (Rx) are a completely different beast. This is a different approach to event handling. There really is a lot of material to cover it, but to make the long story short, instead of attaching event handlers to events, Rx allows you to consider event sequences as ... well, sequences ( IEnumerable<T> ). You can handle events in iterative mode, instead of triggering them asynchronously at arbitrary points in time, when you need to constantly save state in order to detect a series of events occurring in a certain order.
One of the coolest examples I've found in Rx is here . Go to the "Linq to IObservable" section, where it implements a drag and drop handler, which is usually a pain in WPF, in just 4 lines of code. Rx gives you a set of events, something that you actually don't have with regular event handlers, and code snippets like these are also easy to refactor into behavior classes that you can embed anywhere.
What is it. These are some of the more sophisticated features available in .NET 4.0. Of course, there are a few more, but these were the ones you asked for!