TPL Dataflow and async/await vs CCR - part 4
Today I wanted to show a number of simple examples of how to do things with TPL data-flow compared to CCR. Creating a CCR port and posting and then receiving on it asynchronously is one fundamental scenario in CCR. This is what it looks like with TPL data-flow:
1: var port = new BufferBlock<int>();
2: port.Post(42);
3: int result = await port.ReceiveAsync();
If you want to explicitly extract data from a port this is how you would do it:
4: int item;
5: if (port.TryReceive(out item))
6: {
7: ProcessItem(item);
8: }
Very similar to CCR which would just use the Port.Test method on line X. Remember how we in the test coded needed a synchronous way to receive data on a port using ManualResetEvents. Much easier with TPL data-flow:
9: int item = port.Receive();
One larger difference is that in CCR concurrent processing of handlers on ports is the default while in TPL data-flow the default is to process one item at the time. This is how you can change that:
10: var port = new ActionBlock<int>(
11: item => ProcessItem(item),
12: new DataflowBlockOptions
13: { MaxDegreeOfParallelism = Environment.ProcessorCount });
It is also very easy to introduce interleaving as in CCR. That is limit the processing across multiple ports. It can look something like this:
14: var options = new DataflowBlockOptions() {
15: TaskScheduler =
16: new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler
17: };
18: var p1 = new ActionBlock<int>(item => ProcessItem(item), options);
19: var p2 = new ActionBlock<int>(item => ProcessItemDifferent(item), options);
These are just a few differences that should get you started. Bottom line is that if you're used to CCR it is very easy to switch over to use TPL data-flow if you ask me.