Plinq provides the possibility of parallel query processing. To process query operations in parallel, you only need to insert the asparallel method.
But the problem occurs in parallel itself. That is to say, if there is no good synchronization design, the data sequence may be messy and not sorted. Because in parallel execution, a large amount of data can be processed at the same time, but it is not sure which data is processed first. Therefore, in the following example, if the asparallel method is inserted in the query expression, the query results may change.
Query operations not processed in parallel
using System; using System.Linq; using System.Threading.Tasks; class Program { static void Main(string[] args) { int[] ar = { 1, 2, 3 }; var q1 = from n in ar select n; int sum = 1; foreach (var n in q1) { Console.WriteLine("sum={0}×{1}+{1}", sum, n); sum = sum * n + n; } Console.WriteLine("result {0}", sum); } } |
Running result
sum=1×1+1 sum=2×2+2 sum=6×3+3 result 21 |
What if the asparallel method is added to the query expression of this Code as in the following example?
Add the asparallel Method to the query expression
var q1 = from n in ar.AsParallel() select n; |
Running result (the result is uncertain due to the operating system. Here is an example of the result .)
sum=1×1+1 sum=2×3+3 sum=9×2+2 result 20 |
In this case, although the calculation method is not incorrect, the order of the numbers involved in the calculation has changed, so the calculation results are different. To ensure that the calculation content is exactly the same as the calculation result, you need to add the lock-specific object and lock statement as in the following example.
Add lock-specific objects and lock statements
object o = new object(); foreach (var n in q1) { lock (o) { Console.WriteLine("sum={0}×{1}+{1}", sum, n); sum = sum * n + n; } } |
The sorting method is to add the asordered method to the method chain as in the following example, so as to ensure the order remains unchanged.
Sorting Method
var q1 = from n in ar.AsParallel().AsOrdered() select n; |
However, to keep the order unchanged, it definitely means it will affect the processing speed. If you want to maximize the performance, you still need to execute a query unrelated to sorting.
In addition, "Object o = new
Object (); "the code may seem a bit strange. Because the object type needs to be instantiated, the object to be instantiated generally has some function. Although the lock statement can also implement exclusive operations if a specific type of object is used, it is the safest to use an object to solve the synchronization problem.
To sum up, misuse of Plinq is prone to problems involving synchronization and sequence. However, if these two aspects are not involved, you can enjoy the benefits of using Plinq to improve performance in the multi-core era.
■ Summary
1. The task class and Thread class are two similar concepts. It is easy to use the task class.
2. You can pre-schedule the functions to be executed when the task ends.
3. You can simply wait for the completion of multiple tasks.
4. You only need to add the asparallel method to perform parallel query operations.
5. Plinq has problems with synchronization, and the sequence may not remain unchanged.
6. To keep the order unchanged, you need to add the asordered method, but it will affect the performance.