我们还需要Richter的AsyncEnumerator吗?

最近我偶然发现了AsreyEnumerator类表格Jeffrey Richter的Power Threading Library,它似乎解决了我在编写异步内容时经常遇到的几个问题。

这个类的想法已经存在了很长一段时间了,我想知道当前版本的.NET / C#是否已经内置了对这种机制的支持,或者是否仍然需要依赖第三方库? 或者也许新版本的.NET有一些替代方法可以像Richter的AsyncEnumerator那样简化异步编程?

换句话说:今天有没有理由不开始使用Richter的AsyncEnumerator?

编辑:

一些链接与AsyncEnumerator的信息:

  • 杰弗里里希特和他的AsyncEnumerator
  • 使用AsyncEnumerator简化APM
  • 更多AsyncEnumeratorfunction

是的,您仍然可以从我的AsyncEnumerator中受益。 .NET 4中引入的新线程(任务,并行,PLINQ等)都是关于并发性的。 也就是说,它们都是关于计算工作量,将其分解并将其产生到多个线程上,这样工作负载可以在比1个线程完成整个工作负载所需的时间更短的时间内完成。 您可以使用这些构造同时执行多个同步I / O操作。 但是,同步I / O操作会导致所有线程阻塞,从而导致线程池创建更multithreading。 因此,当您的CPU使用率仍然很低时,您的应用程序的资源使用量会急剧上升。 这对于实现您的应用程序来说非常低效,并且会阻止您的应用扩展。

我的AsyncEnumerator就是在不阻塞任何线程的情况下启动异步I / O操作,以便您的应用程序的资源使用率仍然很低,因此您的应用程序可以很好地扩展。 在这种情况下CPU使用率仍然很低,因为您正在执行I / O; 不是计算工作量。

在.NET的下一个版本中,新的async / await语言function(我与Microsoft合作)使您能够执行异步I / O,事实上,新function的建模与我的AsyncEnumerator非常相似。 这么多,您可以将使用我的AsyncEnumerator的代码移植到新模型,只需很少的源代码更改。

正如其他人指出的那样,我的AsyncEnumerator仍然提供其他function,并且适用于.NET 2.0及更高版本。 所以,很多人在很长一段时间内仍然会发现它非常有用。

这里显而易见的是PLINQ,但里希特本人对此表示不满:

杰弗里里希特2008年12月4日下午2:27quotereply他们是非常不同的。 Parallel.For特别是关于执行一系列计算绑定操作,并行扩展到机器中的所有CPU。 我的AsyncEnumerator主要是发出一个或多个并发I / O绑定操作,而没有任何线程阻止它们完成。

但是,C# async CTP在这里可能很有用,使线程延续更加合理,即

 var bytesRead = await stream.ReadAsync(...); Console.WriteLine(bytesRead); // woah! we're on a different thread now! 

在这里,C#编译器重新编写围绕await instuctions的所有内容,这样它就成为现有异步操作(必须返回“等待”值)的回调/继续。 一旦这个生产,我希望这将成为一种更自然的方式来编写由于异步导致内在延迟的代码。

.net 4.0包括PLINQ框架和各种其他线程计算方法。

有关更多详细信息,请参阅.NET Framework中的并行编程 。

从这个问题异步迭代器任务> :

听起来你可能正在寻找的东西就像IObservable ,它有点像基于推送的异步IEnumerable 。 请参阅Microsoft Open Technologies的Rex Extensions,即来自Microsoft Open Technologies的许可代码(Apache-2.0下许可的代码)(无联属关系),这些方法适用于IObservable ,使其像LINQ-to-Objects一样工作。

IEnumerable 的问题在于,没有什么能真正使枚举本身异步。 如果您不想在Rx上添加依赖项(这实际上是使IObservable 闪耀的原因),则此替代方案可能对您有用:

 public async Task> TestAsync(string testString) { return GetChars(testString); } private static IEnumerable GetChars(string testString) { foreach (char c in testString.ToCharArray()) { // do other work yield return c; } } 

虽然我想指出,如果不知道实际上异步做什么,可能有更好的方法来实现你的目标。 您发布的所有代码都不会异步执行任何操作,而且我真的不知道// do other work任何// do other work是否是异步的(在这种情况下,这不是解决您的基本问题,尽管它会使您的代码编译)。