Procedura: utilizzare Parallel.Invoke per eseguire operazioni in paralleloHow to: Use Parallel.Invoke to Execute Parallel Operations

Questo esempio mostra come parallelizzare le operazioni usando Invoke in Task Parallel Library.This example shows how to parallelize operations by using Invoke in the Task Parallel Library. Vengono eseguite tre operazioni in un'origine dati condivisa.Three operations are performed on a shared data source. Poiché nessuna delle operazioni modifica l'origine, possono essere eseguite in parallelo in modo semplice.Because none of the operations modifies the source, they can be executed in parallel in a straightforward manner.

Nota

Questa documentazione usa espressioni lambda per definire delegati in TPL.This documentation uses lambda expressions to define delegates in TPL. Se non si ha familiarità con le espressioni lambda in C# o Visual Basic, vedere Espressioni lambda in PLINQ e TPL.If you are not familiar with lambda expressions in C# or Visual Basic, see Lambda Expressions in PLINQ and TPL.

EsempioExample

namespace ParallelTasks
{
    using System;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Net;

    class ParallelInvoke
    {
        static void Main()
        {
            // Retrieve Darwin's "Origin of the Species" from Gutenberg.org.
            string[] words = CreateWordArray(@"http://www.gutenberg.org/files/2009/2009.txt");

            #region ParallelTasks
            // Perform three tasks in parallel on the source array
            Parallel.Invoke(() =>
                             {
                                 Console.WriteLine("Begin first task...");
                                 GetLongestWord(words);
                             },  // close first Action

                             () =>
                             {
                                 Console.WriteLine("Begin second task...");
                                 GetMostCommonWords(words);
                             }, //close second Action

                             () =>
                             {
                                 Console.WriteLine("Begin third task...");
                                 GetCountForWord(words, "species");
                             } //close third Action
                         ); //close parallel.invoke

            Console.WriteLine("Returned from Parallel.Invoke");
            #endregion

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

        #region HelperMethods
        private static void GetCountForWord(string[] words, string term)
        {
            var findWord = from word in words
                           where word.ToUpper().Contains(term.ToUpper())
                           select word;

            Console.WriteLine(@"Task 3 -- The word ""{0}"" occurs {1} times.",
                term, findWord.Count());
        }

        private static void GetMostCommonWords(string[] words)
        {
            var frequencyOrder = from word in words
                                 where word.Length > 6
                                 group word by word into g
                                 orderby g.Count() descending
                                 select g.Key;

            var commonWords = frequencyOrder.Take(10);

            StringBuilder sb = new StringBuilder();
            sb.AppendLine("Task 2 -- The most common words are:");
            foreach (var v in commonWords)
            {
                sb.AppendLine("  " + v);
            }
            Console.WriteLine(sb.ToString());
        }

        private static string GetLongestWord(string[] words)
        {
            var longestWord = (from w in words
                               orderby w.Length descending
                               select w).First();

            Console.WriteLine("Task 1 -- The longest word is {0}", longestWord);
            return longestWord;
        }


        // An http request performed synchronously for simplicity.
        static string[] CreateWordArray(string uri)
        {
            Console.WriteLine("Retrieving from {0}", uri);

            // Download a web page the easy way.
            string s = new WebClient().DownloadString(uri);

            // Separate string into an array of words, removing some common punctuation.
            return s.Split(
                new char[] { ' ', '\u000A', ',', '.', ';', ':', '-', '_', '/' },
                StringSplitOptions.RemoveEmptyEntries);
        }
        #endregion
    }

    /* Output (May vary on each execution):
        Retrieving from http://www.gutenberg.org/dirs/etext99/otoos610.txt
        Response stream received.
        Begin first task...
        Begin second task...
        Task 2 -- The most common words are:
          species
          selection
          varieties
          natural
          animals
          between
          different
          distinct
          several
          conditions

        Begin third task...
        Task 1 -- The longest word is characteristically
        Task 3 -- The word "species" occurs 1927 times.
        Returned from Parallel.Invoke
        Press any key to exit  
     */
}
' How to: Use Parallel.Invoke to Execute Parallel Operations
Option Explicit On
Option Strict On

Imports System.Threading.Tasks
Imports System.Net

Module ParallelTasks

    Sub Main()
        ' Retrieve Darwin's "Origin of the Species" from Gutenberg.org.
        Dim words As String() = CreateWordArray("http://www.gutenberg.org/files/2009/2009.txt")

        '#Region "ParallelTasks"
        ' Perform three tasks in parallel on the source array
        Parallel.Invoke(Sub()
                            Console.WriteLine("Begin first task...")
                            GetLongestWord(words)
                            ' close first Action
                        End Sub,
            Sub()
                Console.WriteLine("Begin second task...")
                GetMostCommonWords(words)
                'close second Action
            End Sub,
            Sub()
                Console.WriteLine("Begin third task...")
                GetCountForWord(words, "species")
                'close third Action
            End Sub)
        'close parallel.invoke
        Console.WriteLine("Returned from Parallel.Invoke")
        '#End Region

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

#Region "HelperMethods"
    Sub GetCountForWord(ByVal words As String(), ByVal term As String)
        Dim findWord = From word In words _
            Where word.ToUpper().Contains(term.ToUpper()) _
            Select word

        Console.WriteLine("Task 3 -- The word ""{0}"" occurs {1} times.", term, findWord.Count())
    End Sub

    Sub GetMostCommonWords(ByVal words As String())
        Dim frequencyOrder = From word In words _
            Where word.Length > 6 _
            Group By word
            Into wordGroup = Group, Count()
            Order By wordGroup.Count() Descending _
            Select wordGroup

        Dim commonWords = From grp In frequencyOrder
                          Select grp
                          Take (10)

        Dim s As String
        s = "Task 2 -- The most common words are:" & vbCrLf
        For Each v In commonWords
            s = s & v(0) & vbCrLf
        Next
        Console.WriteLine(s)
    End Sub

    Function GetLongestWord(ByVal words As String()) As String
        Dim longestWord = (From w In words _
            Order By w.Length Descending _
            Select w).First()

        Console.WriteLine("Task 1 -- The longest word is {0}", longestWord)
        Return longestWord
    End Function


    ' An http request performed synchronously for simplicity.
    Function CreateWordArray(ByVal uri As String) As String()
        Console.WriteLine("Retrieving from {0}", uri)

        ' Download a web page the easy way.
        Dim s As String = New WebClient().DownloadString(uri)

        ' Separate string into an array of words, removing some common punctuation.
        Return s.Split(New Char() {" "c, ControlChars.Lf, ","c, "."c, ";"c, ":"c, _
        "-"c, "_"c, "/"c}, StringSplitOptions.RemoveEmptyEntries)
    End Function
#End Region


    ' Output (May vary on each execution):
    ' Retrieving from http://www.gutenberg.org/dirs/etext99/otoos610.txt
    ' Response stream received.
    ' Begin first task...
    ' Begin second task...
    ' Task 2 -- The most common words are:
    ' species
    ' selection
    ' varieties
    ' natural
    ' animals
    ' between
    ' different
    ' distinct
    ' several
    ' conditions
    '
    ' Begin third task...
    ' Task 1 -- The longest word is characteristically
    ' Task 3 -- The word "species" occurs 1927 times.
    ' Returned from Parallel.Invoke
    ' Press any key to exit 
    ' 
End Module

Si noti che con Invoke, basta indicare le azioni che si desidera eseguire simultaneamente e il runtime gestisce tutti i dettagli di pianificazione dei thread, tra cui l'adattamento automatico al numero di core nel computer host.Note that with Invoke, you simply express which actions you want to run concurrently, and the runtime handles all thread scheduling details, including scaling automatically to the number of cores on the host computer.

Questo esempio parallelizza le operazioni, ma non i dati.This example parallelizes the operations, not the data. Come approccio alternativo, è possibile parallelizzare le query LINQ usando PLINQ ed eseguire le query in sequenza.As an alternate approach, you can parallelize the LINQ queries by using PLINQ and run the queries sequentially. In alternativa, è possibile parallelizzare i dati usando PLINQ.Alternatively, you could parallelize the data by using PLINQ. Un'altra possibilità consiste nel parallelizzare sia le query che le attività.Another option is to parallelize both the queries and the tasks. Anche se il sovraccarico risultante potrebbe comportare problemi di prestazioni nei computer host con un numero relativamente basso di processori, la scalabilità sarebbe decisamente migliore nei computer con molti processori.Although the resulting overhead might degrade performance on host computers with relatively few processors, it would scale much better on computers with many processors.

Compilazione del codiceCompiling the Code

  • Copiare e incollare l'esempio completo in un progetto di Microsoft Visual Studio 2010 e premere F5.Copy and paste the entire example into a Microsoft Visual Studio 2010 project and press F5.

Vedere ancheSee Also

Programmazione parallelaParallel Programming
Procedura: Annullare un'attività e i relativi figliHow to: Cancel a Task and Its Children
Parallel LINQ (PLINQ)Parallel LINQ (PLINQ)