反应式框架、PLINQ、TPL 和并行扩展如何相互关联? [英] How do Reactive Framework, PLINQ, TPL and Parallel Extensions relate to each other?

查看:41
本文介绍了反应式框架、PLINQ、TPL 和并行扩展如何相互关联?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

至少自 .NET 4.0 发布以来,Microsoft 似乎在支持并行和异步编程方面付出了很多努力,并且似乎已经出现了很多围绕此的 API 和库.尤其是下面这些花哨的名字,最近时常被提及:

At least since the release of .NET 4.0, Microsoft seems to have put a lot of effort in support for parallel and asynchronous programming and it seems a lot of APIs and libraries around this have emerged. Especially the following fancy names are constantly mentioned everywhere lately:

  • 反应式框架,
  • PLINQ(并行 LINQ),
  • TPL(任务并行库)和
  • 并行扩展.

现在它们似乎都是 Microsoft 产品,而且它们似乎都针对 .NET 的异步或并行编程场景.但目前尚不清楚它们中的每一个实际上是什么以及它们如何相互关联.有些可能实际上是同一回事.

Now they all seem to be Microsoft products and they all seem to target asynchronous or parallel programming scenarios for .NET. But it is not quite clear what each of them actually is and how they are related to each other. Some might actually be the same thing.

简而言之,任何人都可以直截了当地说明什么是什么吗?

In a few words, can anyone set the record straight on what is what?

推荐答案

PLINQ (Parallel Linq) 只是一种编写常规 Linq 查询以便它们并行运行的新方法——换句话说,框架将自动负责跨多个线程运行您的查询,以便它们更快地完成(即使用多个 CPU 内核).

PLINQ (Parallel Linq) is simply a new way to write regular Linq queries so that they run in parallel - in other words, the Framework will automatically take care of running your query across multiple threads so that they finish faster (i.e. using multiple CPU cores).

例如,假设您有一堆字符串,并且想要获取所有以字母A"开头的字符串.你可以这样写你的查询:

For example, let's say that you have a bunch of strings and you want to get all the ones that start with the letter "A". You could write your query like this:

var words = new[] { "Apple", "Banana", "Coconut", "Anvil" };
var myWords = words.Select(s => s.StartsWith("A"));

这很好用.但是,如果您有 50,000 个单词要搜索,您可能希望利用每个测试都是独立的这一事实,并将其拆分到多个内核中:

And this works fine. If you had 50,000 words to search, though, you might want to take advantage of the fact that each test is independent, and split this across multiple cores:

var myWords = words.AsParallel().Select(s => s.StartsWith("A"));

这就是将常规查询转换为在多个内核上运行的并行查询所需要做的全部工作.很整洁.

That's all you have to do to turn a regular query into a parallel one that runs on multiple cores. Pretty neat.

TPL(任务并行库)是 PLINQ 的一种补充,它们共同构成了并行扩展.PLINQ 主要基于函数式 编程风格,没有 副作用,而副作用正是 TPL 的用途.如果您想真正并行工作,而不仅仅是并行搜索/选择事物,您可以使用 TPL.

The TPL (Task Parallel Library) is sort of the complement to PLINQ, and together they make up Parallel Extensions. Whereas PLINQ is largely based on a functional style of programming with no side-effects, side-effects are precisely what the TPL is for. If you want to actually do work in parallel as opposed to just searching/selecting things in parallel, you use the TPL.

TPL 本质上是 Parallel 类,它公开了 ForForeachInvoke 的重载.Invoke 有点像在ThreadPool 中排队任务,但使用起来更简单一些.IMO,更有趣的位是 ForForeach.例如,假设您有一大堆要压缩的文件.您可以编写常规顺序版本:

The TPL is essentially the Parallel class which exposes overloads of For, Foreach, and Invoke. Invoke is a bit like queuing up tasks in the ThreadPool, but a bit simpler to use. IMO, the more interesting bits are the For and Foreach. So for example let's say you have a whole bunch of files you want to compress. You could write the regular sequential version:

string[] fileNames = (...);
foreach (string fileName in fileNames)
{
    byte[] data = File.ReadAllBytes(fileName);
    byte[] compressedData = Compress(data);
    string outputFileName = Path.ChangeExtension(fileName, ".zip");
    File.WriteAllBytes(outputFileName, compressedData);
}

同样,这种压缩的每次迭代都完全独立于任何其他迭代.我们可以通过一次执行其中的几个来加快速度:

Again, each iteration of this compression is completely independent of any other. We can speed this up by doing several of them at once:

Parallel.ForEach(fileNames, fileName =>
{
    byte[] data = File.ReadAllBytes(fileName);
    byte[] compressedData = Compress(data);
    string outputFileName = Path.ChangeExtension(fileName, ".zip");
    File.WriteAllBytes(outputFileName, compressedData);
});

再说一次,这就是并行化此操作所需的全部内容.现在,当我们运行我们的 CompressFiles 方法(或我们决定调用它的任何方法)时,它将使用多个 CPU 内核并且可能完成一半或 1/4 的时间.

And again, that's all it takes to parallelize this operation. Now when we run our CompressFiles method (or whatever we decide to call it), it will use multiple CPU cores and probably finish in half or 1/4th the time.

与将其全部放入ThreadPool 相比,这样做的优势在于它实际上同步运行.如果您使用 ThreadPool 代替(或只是简单的 Thread 实例),您必须想出一种方法来找出所有任务何时完成,并且虽然这不是非常复杂,但很多人往往会搞砸或至少遇到麻烦.当您使用Parallel 类时,您实际上不必考虑它;多线程方面对您来说是隐藏的,一切都在幕后处理.

The advantage of this over just chucking it all in the ThreadPool is that this actually runs synchronously. If you used the ThreadPool instead (or just plain Thread instances), you'd have to come up with a way of finding out when all of the tasks are finished, and while this isn't terribly complicated, it's something that a lot of people tend to screw up or at least have trouble with. When you use the Parallel class, you don't really have to think about it; the multi-threading aspect is hidden from you, it's all handled behind the scenes.

Reactive Extensions (Rx) 真的是完全不同的野兽.这是考虑事件处理的不同方式.关于这一点真的有很多材料要介绍,但长话短说,Rx 不是将事件处理程序连接到事件,而是让您将事件序列视为……好吧,序列 (IEnumerable;).您可以以迭代方式处理事件,而不是让它们在随机时间异步触发,在这种情况下,您必须始终保存状态,以便检测以特定顺序发生的一系列事件.

Reactive Extensions (Rx) are really a different beast altogether. It's a different way of thinking about event handling. There's really a lot of material to cover on this, but to make a long story short, instead of wiring up event handlers to events, Rx lets you treat sequences of events as... well, sequences (IEnumerable<T>). You get to process events in an iterative fashion instead of having them fired asynchronously at random times, where you have to keep saving state all the time in order to detect a series of events happening in a particular order.

我发现的最酷的 Rx 示例之一是 这里.跳到Linq to IObservable"部分,在那里他仅用 4 行代码实现了拖放处理程序,这在 WPF 中通常很麻烦.Rx 为您提供了事件组合,这是您在常规事件处理程序中没有的东西,并且像这样的代码片段也可以直接重构为可以放入任何地方的行为类.

One of the coolest examples I've found of Rx is here. Skip down to the "Linq to IObservable" section where he implements a drag-and-drop handler, which is normally a pain in WPF, in just 4 lines of code. Rx gives you composition of events, something you don't really have with regular event handlers, and code snippets like these are also straightforward to refactor into behaviour classes that you can sleeve in anywhere.

就是这样.这些是 .NET 4.0 中提供的一些更酷的功能.当然还有更多,但这些是你问的那些!

And that's it. These are some of the cooler features that are available in .NET 4.0. There are several more, of course, but these were the ones you asked about!

这篇关于反应式框架、PLINQ、TPL 和并行扩展如何相互关联?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆