Procedura: creare ed eseguire una query PLINQ semplice

Nell'esempio riportato in questo articolo viene illustrato come creare una semplice query LINQ (Parallel Language Integrated Query) usando il metodo di estensione ParallelEnumerable.AsParallel nella sequenza di origine ed eseguendo la query usando il metodo ParallelEnumerable.ForAll.

Nota

Le espressioni lambda sono usate nella documentazione per definire i delegati in PLINQ. Se non si ha familiarità con le espressioni lambda in C# o Visual Basic, vedere Espressioni lambda in PLINQ e TPL.

Esempio

using System;
using System.Linq;

class ExampleForAll
{
    public static void Main()
    {
        var source = Enumerable.Range(100, 20000);

        // Result sequence might be out of order.
        var parallelQuery =
            from num in source.AsParallel()
            where num % 10 == 0
            select num;

        // Process result sequence in parallel
        parallelQuery.ForAll((e) => DoSomething(e));

        // Or use foreach to merge results first.
        foreach (var n in parallelQuery)
        {
            Console.WriteLine(n);
        }

        // You can also use ToArray, ToList, etc as with LINQ to Objects.
        var parallelQuery2 =
            (from num in source.AsParallel()
             where num % 10 == 0
             select num).ToArray();

        // Method syntax is also supported
        var parallelQuery3 =
            source.AsParallel()
                .Where(n => n % 10 == 0)
                .Select(n => n);

        Console.WriteLine("\nPress any key to exit...");
        Console.ReadLine();
    }

    static void DoSomething(int _) { }
}

Public Class Program
    Public Shared Sub Main()
        Dim source = Enumerable.Range(100, 20000)

        ' Result sequence might be out of order.
        Dim parallelQuery = From num In source.AsParallel()
                            Where num Mod 10 = 0
                            Select num

        ' Process result sequence in parallel
        parallelQuery.ForAll(Sub(e)
                                 DoSomething(e)
                             End Sub)

        ' Or use For Each to merge results first
        ' as in this example, Where results must
        ' be serialized sequentially through static Console method.
        For Each n In parallelQuery
            Console.Write("{0} ", n)
        Next

        ' You can also use ToArray, ToList, etc, as with LINQ to Objects.
        Dim parallelQuery2 = (From num In source.AsParallel()
                              Where num Mod 10 = 0
                              Select num).ToArray()

        ' Method syntax is also supported
        Dim parallelQuery3 =
            source.AsParallel().Where(Function(n)
                                          Return (n Mod 10) = 0
                                      End Function).Select(Function(n)
                                                               Return n
                                                           End Function)

        For Each i As Integer In parallelQuery3
            Console.Write($"{i} ")
        Next


        Console.WriteLine()
        Console.WriteLine("Press any key to exit...")
        Console.ReadLine()
    End Sub

    ' A toy function to demonstrate syntax. Typically you need a more
    ' computationally expensive method to see speedup over sequential queries.
    Shared Sub DoSomething(ByVal i As Integer)
        Console.Write($"{Math.Sqrt(i):###.##} ")
    End Sub
End Class

Questo esempio illustra il modello di base per la creazione e l'esecuzione di qualsiasi query Parallel LINQ nei casi in cui l'ordine della sequenza di risultati non è importante. Le query non ordinate sono in genere più veloci rispetto alle query ordinate. La query partiziona l'origine in attività eseguita in modo asincrono su più thread. L'ordine di completamento di ogni attività dipende non solo dalla quantità di lavoro necessario per l'elaborazione degli elementi nella partizione, ma anche da fattori esterni, ad esempio il modo in cui il sistema operativo pianifica ogni thread. Lo scopo di questo esempio consiste nell'illustrare l'uso ed è possibile che l'esecuzione non sia più veloce rispetto alla query LINQ to Objects sequenziale equivalente. Per altre informazioni sull'aumento di velocità, vedere Informazioni sull'aumento di velocità in PLINQ. Per altre informazioni su come mantenere l'ordinamento degli elementi in una query, vedere Procedura: Controllare l'ordinamento in una query PLINQ.

Vedi anche