繁体   English   中英

我们还需要Richter的AsyncEnumerator吗?

[英]Do we still need Richter's AsyncEnumerator?

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

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

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

编辑:

一些链接与AsyncEnumerator的信息:

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

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

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

正如其他人所指出的,我的AsyncEnumerator仍然提供其他功能,并且可以与.NET 2.0及更高版本一起使用。 因此,许多人在很长一段时间内仍然会发现它非常有用。

这里有一个明显的平行点是PLINQ,但里希特本人对此表示不满:

Jeffrey Richter 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实例的所有内容,这样它就会成为现有异步操作(必须返回“等待”值)的回调/延续。 一旦这个生产,我希望这将成为一种更自然的方式来编写由于异步导致内在延迟的代码。

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

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

从这个问题异步迭代器任务<IEnumerable <T >>

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

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

public async Task<IEnumerable<char>> TestAsync(string testString)
{
    return GetChars(testString);
}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM