Gör så här: Skriva en anpassad PLINQ-mängdfunktion

Det här exemplet visar hur du använder metoden Aggregate för att tillämpa en anpassad aggregeringsfunktion på en källsekvens.

Varning

Det här exemplet syftar till att visa användningen och kanske inte kör snabbare än en motsvarande sekventiell LINQ-till-objekt-fråga. Mer information om att förstå hastighetsökning i PLINQ finns i Understanding Speedup in PLINQ.

Exempel

I följande exempel beräknas standardavvikelsen för en sekvens med heltal.

namespace PLINQAggregation
{
    using System;
    using System.Linq;

    class aggregation
    {
        static void Main(string[] args)
        {

            // Create a data source for demonstration purposes.
            int[] source = new int[100000];
            Random rand = new Random();
            for (int x = 0; x < source.Length; x++)
            {
                // Should result in a mean of approximately 15.0.
                source[x] = rand.Next(10, 20);
            }

            // Standard deviation calculation requires that we first
            // calculate the mean average. Average is a predefined
            // aggregation operator, along with Max, Min and Count.
            double mean = source.AsParallel().Average();

            // We use the overload that is unique to ParallelEnumerable. The
            // third Func parameter combines the results from each thread.
            double standardDev = source.AsParallel().Aggregate(
                // initialize subtotal. Use decimal point to tell
                // the compiler this is a type double. Can also use: 0d.
                0.0,

                 // do this on each thread
                 (subtotal, item) => subtotal + Math.Pow((item - mean), 2),

                 // aggregate results after all threads are done.
                 (total, thisThread) => total + thisThread,

                // perform standard deviation calc on the aggregated result.
                (finalSum) => Math.Sqrt((finalSum / (source.Length - 1)))
            );
            Console.WriteLine($"Mean value is = {mean}");
            Console.WriteLine($"Standard deviation is {standardDev}");
            Console.ReadLine();
        }
    }
}
Class aggregation
    Private Shared Sub Main(ByVal args As String())

        ' Create a data source for demonstration purposes.
        Dim source As Integer() = New Integer(99999) {}
        Dim rand As New Random()
        For x As Integer = 0 To source.Length - 1
            ' Should result in a mean of approximately 15.0.
            source(x) = rand.[Next](10, 20)
        Next

        ' Standard deviation calculation requires that we first
        ' calculate the mean average. Average is a predefined
        ' aggregation operator, along with Max, Min and Count.
        Dim mean As Double = source.AsParallel().Average()


        ' We use the overload that is unique to ParallelEnumerable. The 
        ' third Func parameter combines the results from each thread.
        ' initialize subtotal. Use decimal point to tell 
        ' the compiler this is a type double. Can also use: 0d.

        ' do this on each thread

        ' aggregate results after all threads are done.

        ' perform standard deviation calc on the aggregated result.
        Dim standardDev As Double = source.AsParallel().Aggregate(0.0R, Function(subtotal, item) subtotal + Math.Pow((item - mean), 2), Function(total, thisThread) total + thisThread, Function(finalSum) Math.Sqrt((finalSum / (source.Length - 1))))
        Console.WriteLine("Mean value is = {0}", mean)
        Console.WriteLine("Standard deviation is {0}", standardDev)

        Console.ReadLine()
    End Sub
End Class

I det här exemplet används en överlagring av den aggregerade standardfrågeoperatorn som är unik för PLINQ. Den här överbelastningen tar en extra System.Func<T1,T2,TResult> som den tredje ingångsparametern. Det här ombudet kombinerar resultaten från alla trådar innan det utför den slutliga beräkningen av de aggregerade resultaten. I det här exemplet lägger vi ihop summorna från alla trådar.

Observera att när kroppen av ett lambda-uttryck består av ett enda uttryck är returvärdet från System.Func<T,TResult> delegeringen uttryckets värde.

Se även