如何:使用 Parallel.Invoke 来执行并行操作
此示例演示如何使用任务并行库中的 ParallelInvoke() 对操作进行并行化。 将对共享数据源执行三项操作。 由于任何这些操作都不修改源,因此它们可以直接并行执行。
注意 |
---|
本文档使用 lambda 表达式在 TPL 中定义委托。如果您不熟悉 C# 或 Visual Basic 中的 lambda 表达式,请参见 在 PLINQ 和 TPL 中的 Lambda 表达式。 |
示例
' 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
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
*/
}
请注意,借助 Invoke(),您只需表述出希望要哪些操作同时运行,运行时将处理所有线程调度详情,包括依据主计算机上的内核数自动缩放。
此示例对操作(而不是数据)进行并行化。 作为替代方法,您可以使用 PLINQ 对 LINQ 查询进行并行化,并按顺序运行这些查询。 或者,您可以使用 PLINQ 对数据进行并行化。 另一个选项是同时对查询和任务进行并行化。 尽管所产生的开销可能会降低处理器数量相对较少的主计算机上的性能,但在具有多个处理器的计算机上,它的缩放性能将好得多。
编译代码
- 将整个示例复制并粘贴到 Microsoft Visual Studio 2010 项目中,并按 F5。