如何才能充分利用 .NET 4.0 中新增强的并行性功能?
我对使用 .NET 4.0 中新增强的并行性功能非常感兴趣。
我还看到了在 F# 中使用它的一些可能性,就像在 C# 中一样。
尽管如此,我只能看到 PLINQ 必须提供的内容,例如以下内容:
var query = from c in Customers.AsParallel()
where (c.Name.Contains("customerNameLike"))
select c;
这种并行性肯定还有其他用途。
您还有其他使用它的例子吗?这是特别转向 PLINQ,还是有其他像 PLINQ 一样简单的用法?
谢谢! =)
I am pretty much interested into using the newly enhanced Parallelism features in .NET 4.0.
I have also seen some possibilities of using it in F#, as much as in C#.
Despite, I can only see what PLINQ has to offer with, for example, the following:
var query = from c in Customers.AsParallel()
where (c.Name.Contains("customerNameLike"))
select c;
There must for sure be some other use of this parallelism thing.
Have you any other examples of using it? Is this particularly turned toward PLINQ, or are there other usage as easy as PLINQ?
Thanks! =)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(3)
我的团队也刚刚完成了一本关于此的书...
使用 Microsoft® .NET 进行并行编程:
多核架构上的分解和协调设计模式
Colin Campbell、Ralph Johnson、Ade Miller 和 Stephen Toub。前言:Tony Hey
您可以在此处下载草稿和示例:http://parallelpatterns.codeplex.com/
完整的书将于本月晚些时候在 MSDN 上发布,并于 10 月在亚马逊上发布。
对于明目张胆的插件表示歉意,但我认为您可能会发现这些内容确实很有帮助。
更新...
为了回答您选择的问题(如下),聚合的实现(从列表中根据列表内容创建聚合)恰好比 PLinq 更好地映射到 PLinq替代方案,Parallel.ForEach。 PDF 的 p72 上有一个使用 Parallel.ForEach 进行聚合的示例。
如果您只想使用 PLinq 更新集合的内容,则映射要简单得多。例如,以下代码循环访问帐户列表,计算余额趋势并标记预测余额超过透支限额的帐户。
Sequential:
static void UpdatePredictionsSequential(AccountRepository accounts)
{
foreach (Account account in accounts.AllAccounts)
{
Trend trend = SampleUtilities.Fit(account.Balance);
double prediction = trend.Predict(account.Balance.Length + NumberOfMonths);
account.SeqPrediction = prediction;
account.SeqWarning = prediction < account.Overdraft;
}
}
PLinq:
static void UpdatePredictionsPlinq(AccountRepository accounts)
{
accounts.AllAccounts
.AsParallel()
.ForAll(account =>
{
Trend trend = SampleUtilities.Fit(account.Balance);
double prediction = trend.Predict(account.Balance.Length + NumberOfMonths);
account.PlinqPrediction = prediction;
account.PlinqWarning = prediction < account.Overdraft;
});
}
Parallel.ForEach:
static void UpdatePredictionsParallel(AccountRepository accounts)
{
Parallel.ForEach(accounts.AllAccounts, account =>
{
Trend trend = SampleUtilities.Fit(account.Balance);
double prediction = trend.Predict(account.Balance.Length + NumberOfMonths);
account.ParPrediction = prediction;
account.ParWarning = prediction < account.Overdraft;
});
}
在某些情况下,PLinq 可能是最具表现力的选择。在其他情况下,Parallel.For/ForEach 可能更好,在某些情况下,这很大程度上取决于程序员的偏好。
但是,任务并行库支持的不仅仅是并行循环和聚合模式。它允许您构建计划在多核硬件上并行执行的任务(任务并行模式):
static int ParallelTaskImageProcessing(Bitmap source1, Bitmap source2,
Bitmap layer1, Bitmap layer2, Graphics blender)
{
Task toGray = Task.Factory.StartNew(() => SetToGray(source1, layer1));
Task rotate = Task.Factory.StartNew(() => Rotate(source2, layer2));
Task.WaitAll(toGray, rotate);
Blend(layer1, layer2, blender);
return source1.Width;
}
它允许您创建任务图,其中一个任务的输出被输入到另一个任务中(任务图或期货模式):
public static int Example4()
{
var a = 22;
var cf = Task<int>.Factory.StartNew(() => F2(a));
var df = cf.ContinueWith((t) => F3(t.Result));
var b = F1(a);
var f = F4(b, df.Result);
return f;
}
其中 F1 -F4 是输入和输出具有依赖性的函数。
它支持创建依赖任务树,以解决排序等分而治之的问题(动态任务并行模式):
static void ParallelWalk<T>(Tree<T> tree, Action<T> action)
{
if (tree == null) return;
var t1 = Task.Factory.StartNew(
() => action(tree.Data));
var t2 = Task.Factory.StartNew(
() => ParallelWalk(tree.Left, action));
var t3 = Task.Factory.StartNew(
() => ParallelWalk(tree.Right, action));
Task.WaitAll(t1, t2, t3);
}
它还实现了多个(线程安全)集合以在并行程序中使用。例如,它允许直接实现管道模式:
static void Chapter7Example01Pipeline(int seed)
{
Console.Write("Begin Pipelined Sentence Builder");
var buffer1 = new BlockingCollection<string>(BufferSize);
var buffer2 = new BlockingCollection<string>(BufferSize);
var buffer3 = new BlockingCollection<string>(BufferSize);
var f = new TaskFactory(TaskCreationOptions.LongRunning,
TaskContinuationOptions.None);
var stage1 = f.StartNew(() => ReadStrings(buffer1, seed));
var stage2 = f.StartNew(() => CorrectCase(buffer1, buffer2));
var stage3 = f.StartNew(() => CreateSentences(buffer2, buffer3));
var stage4 = f.StartNew(() => WriteSentences(buffer3));
Task.WaitAll(stage1, stage2, stage3, stage4);
}
上述所有功能还包含对异常处理和取消的支持,尽管为了清楚起见,我没有在此处显示它们。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
.NET 4 中提供的新并行编程功能不仅限于 PLINQ。
正如 Microsoft 所言:“Visual Studio 2010 和 .NET Framework 4 通过提供新的运行时、新的类库类型和新的诊断工具,增强了对并行编程的支持。这些功能简化了并行开发,使您可以高效地编写代码以自然的方式编写细粒度且可扩展的并行代码,而无需直接使用线程或线程池。”
我建议您查看 .NET Framework 中的并行编程 是一个很好的起点。
总体而言,.NET 4 和 Visual Studio 2010 提供以下功能:
编程
ThreadPool及其基类
我个人
发现任务并行库中的 Task 和 Task{T} 类在创建和协调异步工作时更加灵活。
The new parallel programming features provided in .NET 4 are not limited to just PLINQ.
As stated by Microsoft: "Visual Studio 2010 and the .NET Framework 4 enhance support for parallel programming by providing a new runtime, new class library types, and new diagnostic tools. These features simplify parallel development so that you can write efficient, fine-grained, and scalable parallel code in a natural idiom without having to work directly with threads or the thread pool."
I would recommend that you review Parallel Programming in the .NET Framework as a good starting place.
Overall, .NET 4 and Visual Studio 2010 provide these features:
Programming
ThreadPool and the base class
libraries
I personally have found the Task and Task{T} classes in the Task Parallel Library to be more flexible when creating and coordinating asynchronous work.