简体   繁体   English

我们还需要Richter的AsyncEnumerator吗?

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

Recently I stumbled across the AsyncEnumerator class form Jeffrey Richter's Power Threading Library which seems to solve several problems I'm usually encountering when programming asynchronous stuff. 最近我偶然发现了AsreyEnumerator类表格Jeffrey Richter的Power Threading Library,它似乎解决了我在编写异步内容时经常遇到的几个问题。

The idea for this class has been around for quite a while now and I'm wondering if current versions of .NET / C# have built-in support for this mechanism by now or if it is still necessary to rely on a third party library? 这个类的想法已经存在了很长一段时间了,我想知道当前版本的.NET / C#现在是否内置了对这种机制的支持,或者是否仍然需要依赖第三方库? Or maybe newer versions of .NET have some alternative approach which simplifies asynchronous programming as much as Richter's AsyncEnumerator does? 或者也许新版本的.NET有一些替代方法可以像Richter的AsyncEnumerator那样简化异步编程?

Or in other words: Is there a reason to not start using Richter's AsyncEnumerator today? 或者换句话说:今天有没有理由不开始使用Richter的AsyncEnumerator?

Edit: 编辑:

Some links with information on AsyncEnumerator: 一些链接与AsyncEnumerator的信息:

Yes, you will still benefit from my AsyncEnumerator. 是的,您仍然可以从我的AsyncEnumerator中受益。 The new threading stuff introduced in .NET 4 (Tasks, Parallel, PLINQ, etc), is all about concurrency. .NET 4(Tasks,Parallel,PLINQ等)中引入的新线程内容都是关于并发性的。 That is, they are all about taking a computational workload, dividing it up and spawning it out onto multiple threads so that the workload can complete in less time than it would takes 1 thread to do the entire workload. 也就是说,它们都是关于计算工作量,将其分解并将其产生到多个线程上,以便工作负载可以在比1个线程完成整个工作负载所需的时间更短的时间内完成。 You can use these constructs to execute multiple synchronous I/O operations concurrently. 您可以使用这些构造同时执行多个同步I / O操作。 However, the synchronous I/O operations cause all the threads to block which then causes the threadpool to create more threads. 但是,同步I / O操作会导致所有线程被阻塞,从而导致线程池创建更多线程。 And so, your app's resource usage skyrockets while your CPU usage remains very low. 因此,当您的CPU使用率仍然很低时,您的应用程序的资源使用量会急剧上升。 This is a very inefficient to implement your application and prevents your app from scaling. 这对于实现您的应用程序来说非常低效,并且会阻止您的应用扩展。

My AsyncEnumerator is all about initiating asynchronous I/O operations without blocking any threads so that your app's resource usage remains very low so your app scales very well. 我的AsyncEnumerator就是在不阻塞任何线程的情况下启动异步I / O操作,这样您的应用程序的资源使用率仍然非常低,因此您的应用程序可以很好地扩展。 CPU usage remains low in this case too because you are performing I/O; 在这种情况下CPU使用率仍然很低,因为您正在执行I / O; not a computational workload. 不是计算工作量。

In the next version of .NET, the new async/await language features (which I worked on with Microsoft), enables you to perform async I/O and in fact, the new features are modeled very similar to my AsyncEnumerator. 在.NET的下一个版本中,新的async / await语言功能(我与Microsoft合作)使您能够执行异步I / O,事实上,新功能的建模与我的AsyncEnumerator非常相似。 So much so that you can port code that uses my AsyncEnumerator to the new model with very few source code changes. 这么多,您可以将使用我的AsyncEnumerator的代码移植到新模型,只需很少的源代码更改。

As someone else pointed out, my AsyncEnumerator still offers other features and works with .NET 2.0 and later. 正如其他人所指出的,我的AsyncEnumerator仍然提供其他功能,并且可以与.NET 2.0及更高版本一起使用。 So, many people will still find it quite useful for a long time. 因此,许多人在很长一段时间内仍然会发现它非常有用。

An obvious parallel here is PLINQ, but Richter himself dismisses this : 这里有一个明显的平行点是PLINQ,但里希特本人对此表示不满:

Jeffrey Richter Dec 04, 2008 at 2:27 PMquotereply They are very different. Jeffrey Richter 2008年12月4日下午2:27quotereply他们非常不同。 Parallel.For in particular is about performing a bunch of compute-bound operations in parallel scaling out across all the CPUs in teh machine. Parallel.For特别是关于执行一系列计算绑定操作,并行扩展到机器中的所有CPU。 My AsyncEnumerator is mostly about issuing one or more concurrent I/O-bound operations without have any threads block for them to complete. 我的AsyncEnumerator主要是发出一个或多个并发I / O绑定操作,而没有任何线程阻止它们完成。

However, the C# async CTP may be useful here, making thread continuations much more reasonable, ie 但是,C# async CTP在这里可能很有用,使线程延续更加合理,即

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

Here, the C# compiler re-writes everything around await instuctions, such that it becomes a callback/continuation to the existing async operation (which must return an "awaitable" value). 在这里,C#编译器会重新编写await实例的所有内容,这样它就会成为现有异步操作(必须返回“等待”值)的回调/延续。 Once this is in production, I hope this will become a much more natural way to write code with intrinsic delays due to async. 一旦这个生产,我希望这将成为一种更自然的方式来编写由于异步导致内在延迟的代码。

.net 4.0 includes the PLINQ framework and various other means of threaded computation. .net 4.0包括PLINQ框架和各种其他线程计算方法。

See Parallel Programming in the .NET Framework for more details. 有关更多详细信息,请参阅.NET Framework中的并行编程

From this question Asynchronous iterator Task<IEnumerable<T>> : 从这个问题异步迭代器任务<IEnumerable <T >>

It sounds like what you may really be looking for is something like IObservable<T> , which is sort of like a push-based asynchronous IEnumerable<T>. 听起来你可能正在寻找的东西就像IObservable <T> ,它有点像基于推送的异步IEnumerable <T>。 See Reactive Extensions, aka Rx from Microsoft Open Technologies (code licensed under Apache-2.0) (no affiliation) for a huge host of methods that work with IObservable<T> to make it work like LINQ-to-Objects and more. 请参阅Microsoft Open Technologies的Rex Extensions,即来自Microsoft Open Technologies的许可证(在Apache-2.0下获得许可的代码)(无联属关系),这些方法适用于IObservable <T>,使其像LINQ-to-Objects一样工作。

The problem with IEnumerable<T> is that there's nothing that really makes the enumeration itself asynchronous. IEnumerable <T>的问题在于,没有什么能真正使枚举本身异步。 If you don't want to add a dependency on Rx (which is really what makes IObservable<T> shine), this alternative might work for you: 如果您不想在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;
    }
}

though I'd like to point out that without knowing what's **actually being done asynchronously, there may be a much better way to accomplish your goals. 虽然我想指出,如果不知道实际上异步做什么,可能会有更好的方法来实现你的目标。 None of the code you posted will actually do anything asynchronously, and I don't really know if anything in // do other work is asynchronous (in which case, this isn't a solution to your underlying problem though it will make your code compile). 您发布的代码中没有一个实际上会异步执行任何操作,而且我真的不知道// do other work任何// do other work是否异步(在这种情况下,这不是解决您的基本问题,尽管它会使您的代码编译)。

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

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