返回介绍

如何:使用 Parallel.Invoke 来执行并行操作

发布于 2025-02-23 23:16:16 字数 7510 浏览 0 评论 0 收藏 0

此示例演示如何通过使用任务并行库中的 Invoke 并行操作。 共享的数据源上执行三个操作。 因为操作均不修改源,所以可以直接的方式并行执行。

备注

本文档使用 lambda 表达式在 TPL 中定义委托。 如果不熟悉 C# 或 Visual Basic 中的 lambda 表达式,请参阅 PLINQ 和 TPL 中的 Lambda 表达式 。

示例

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

请注意,借助 Invoke ,你只需表达想同时运行的操作,运行时会处理所有线程计划详细信息(包括自动缩放至主计算机上的内核数)。

此示例并行操作,而非数据。 此外,可使用 PLINQ 并行 LINQ 查询,并按顺序运行查询。 或者,可使用 PLINQ 并行数据。 另一个选项是并行查询和任务。 尽管生成的开销在处理器相对较少的主机计算机上可能会降低性能,但在处理器较多的计算机上可进行更好的缩放。

编译代码

  • 将完整示例复制和粘贴到 Microsoft Visual Studio 2010 项目,并按 F5 键。

另请参阅

并行编程
如何:取消任务及其子级
并行 LINQ (PLINQ)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文