Jeffrey Richter does a video about his AsyncEnumerator for the C# team and Channel 9

Jeffrey Richter

View Comments

  • The chance of this happenning is very slim. I presented this to the CLR team quite some time ago and while they liked it a lot they felt that having a method that returns IEnumerator and having "yield return" statements in the code felt unnatural and so they want to do something first class. This means chaning the CLR and having new language constructs. These changes will deffinitely not be in .NET 4.0 and I doubt that they will be in .NET 5.0. And so, while it would be nice for them to put something like this in .NET proper, it will be many years before they do. People need a solution that works today on .NET 2.0 and later and my AsyncEnumerator fills this bill nicely.

  • I think the way Jeffery thought is really new one as he's using synchronous means to utilize asynchronous. I think this may help us to think about how to use sync coding techniques for async programming.

  • I certainly agree with your comments about server-side code. However, I disagree with your thoughts about client-side code. On my machine Outlook (just to pick some app as an example) has over 50 threads in it because the Outlook developers have the mindset that it isn't bad to just spawn off a few more threads and allocate a few more megabytes of memory. However, this wastes a lot of resources and if Outlook is running on a terminal server machine hosting 100 client sessions, then that means 5,000 threads on the system! In fact, because this problem is so bad, Windows 7 is doing a lot to reduce the number of threads used throughout system services and applications that ship with the OS so that Windows 7 will run well on small footprint machines with only 1GB of RAM in them. Clearly the Windows team feels that all the threads they have been creating has been hurting them and they are finally doing something about it.
    And, since I'd like to make things better for Windows users, I highly recommend asynchrounous programming for client-side applications. Also, delegates DO support the APM via their BeginInvoke/EndInvoke methods and because of this, asynchronous delegate invocations integrate quite nicely with my AsyncEnumerator. In addition, my AsyncEnumerator automatically marshals the result back to the GUI thread so there is no need to call Control's BeginInvoke method (for Windows Forms) or DispatcherObject's BeginIvoke method (for WPF). Furthermore, my AE offers cancelation/timeout support as well as discard support which are all useful features for client-side applications that you do not get with the APM alone or by just spawning up another thread.
    ASP.NET does support the ability for developers to implement their web form or web service app asynchronously but few developers take advantage of this. However, ASP.NET offers it as an option because it does not simply give it to you by default. Also, it is very useful to perform async programming when accessing a DB because the DB IS a bottleneck (as you point out). If you make synchronous requests to a DB then your server will create a ton of threads which are all blocked; your server will handle just a few concurrent requests and memory consumption will be very high with thread stacks which your code is not using at all.
    In the real world, there are many developers who will avoid high-level synchronous libraries in order to gain scalability. I know that MS does avoid synchronous DB access for Hotmail and many of its other highly-scalable services. However, it is true, that if your service has few concurrent users, then you do get a lot of benefit from various synchronous abstractions (like Linq to SQL). In an ideal world, these abstractions that offer such productivity will offer asynchronous ways of using them. Linq to SQL doesn't offer this today but it could in the future (or Linq to Entities could).
    And, as for refactoring...Iterators do offer some challenges here, I agree. However, from an iterator, you can call compute-bound synchronous methods or methods that initiate an asynchronous compute-bound or I/O-bound operation that itself returns an IAsyncResult. And, also my AsyncEnumerator does support composition where an iterator can invoke another iterator. For example, you could create an iterator that asynchronously queries a web server to get some data and process it. And then, you can create another iterator that consumes the first in a loop to do asynchronous processing for several web sites. In fact, all of this processing can happen concurrently allowing for phenominal scaling. If your iterator methods get overwhelming, then you can resort to call back methods which is what all native applications have to do and what developers writing scalable managed application have to do today. Iterators give you a new ability; they don't take away any of the old abilities. This ability has very few drawbacks but if you come across one, then don't use it; go back to an older tried and true way.

Recent Posts

8-Step AWS to Microsoft Azure Migration Strategy

Microsoft Azure and Amazon Web Services (AWS) are two of the most popular cloud platforms.…

5 days ago

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

2 weeks ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

4 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago