Condividi tramite


Procedura: Specificare le opzioni di unione in PLINQ

In questo esempio viene illustrato come specificare le opzioni di unione che verranno applicate a tutti gli operatori successivi in una query PLINQ. Non è necessario impostare le opzioni di unione in modo esplicito, ma in questo modo è possibile migliorare le prestazioni. Per altre informazioni sulle opzioni di unione, vedere Opzioni di merge in PLINQ.

Avvertimento

Questo esempio è pensato per illustrare l'uso e potrebbe non essere eseguito più rapidamente rispetto alla query sequenziale equivalente di LINQ to Objects. Per altre informazioni sull'accelerazione, vedere Comprendere l'Accelerazione in PLINQ.

Esempio

Nell'esempio seguente viene illustrato il comportamento delle opzioni di unione in uno scenario di base con un'origine non ordinata e viene applicata una funzione costosa a ogni elemento.

namespace MergeOptions
{
    using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Threading;

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

            var nums = Enumerable.Range(1, 10000);

            // Replace NotBuffered with AutoBuffered
            // or FullyBuffered to compare behavior.
            var scanLines = from n in nums.AsParallel()
                                .WithMergeOptions(ParallelMergeOptions.NotBuffered)
                            where n % 2 == 0
                            select ExpensiveFunc(n);

            Stopwatch sw = Stopwatch.StartNew();
            foreach (var line in scanLines)
            {
                Console.WriteLine(line);
            }

            Console.WriteLine($"Elapsed time: {sw.ElapsedMilliseconds} ms. Press any key to exit.");
            Console.ReadKey();
        }

        // A function that demonstrates what a fly
        // sees when it watches television :-)
        static string ExpensiveFunc(int i)
        {
            Thread.SpinWait(2000000);
            return string.Format("{0} *****************************************", i);
        }
    }
}
Class MergeOptions2
    Sub DoMergeOptions()

        Dim nums = Enumerable.Range(1, 10000)

        ' Replace NotBuffered with AutoBuffered
        ' or FullyBuffered to compare behavior.
        Dim scanLines = From n In nums.AsParallel().WithMergeOptions(ParallelMergeOptions.NotBuffered)
                        Where n Mod 2 = 0
                        Select ExpensiveFunc(n)

        Dim sw = Stopwatch.StartNew()
        For Each line In scanLines
            Console.WriteLine(line)
        Next

        Console.WriteLine("Elapsed time: {0} ms. Press any key to exit.")
        Console.ReadKey()

    End Sub
    ' A function that demonstrates what a fly
    ' sees when it watches television :-)
    Function ExpensiveFunc(ByVal i As Integer) As String
        Threading.Thread.SpinWait(2000000)
        Return String.Format("{0} *****************************************", i)
    End Function
End Class

Nei casi in cui l'opzione AutoBuffered comporta una latenza indesiderata prima che venga restituito il primo elemento, provare l'opzione NotBuffered per produrre elementi di risultato più velocemente e senza problemi.

Vedere anche