In the previous chapter, we have already used TPL to simplify the writing of some fine-grained parallel code. The code looked quite clear; however, TPL is a quite complicated framework with a high level of abstraction, and it deserves a detailed review.
Most code samples that we have seen so far were quite simple in terms of composition. We took a computational problem, split it into several independent parts, and ran these parts on different worker threads. When all the parts are completed, we get their results and combine them into a final calculation result. However, most real-world programs usually have a complex structure. We need to get input data, and then there are program stages that depend on each other; to continue the calculations, we have to get results from previous stages. These stages can take different durations to complete and require different approaches for parallelization.
It is possible to write this logic based on worker threads...