none
Is IAsyncEnumerator dead? RRS feed

Answers

  • There's no current investment in this area but we'll consider posting an update that works well against .NET 4.5.

    At the same time, we'd like users to think about the chunky/chatty nature of data retrieval for their scenarios. One of the drawbacks of the async enumerator approach is the very chatty one-element-at-a-time nature, which has some performance price. Though things have been improved significantly in the .NET 4.5 RTM final design on await (e.g. bypassing the awaiter continuation, sync ctx, and execution ctx hops in case the operation already completed), the case where every element retrieval is truly asynchronous has still non-negligible overhead in the async method state machine and task awaiters. (In fact, you may want to restructure the code such that you always obtain the next iteration's Task<bool> to await it after processing the current iteration, as to maximize the chance of synchronous completion and reduced awaiter hoops.) Rx's overhead for element-by-element retrieval is far less (just virtual method calls), but is push-based.

    Most likely, a pull-based async enumeration will ultimately use a data retrieval source that's not as chatty as it seems (e.g. database readers often send multi-record buffers to the client). Reflecting this batchy nature to the layers above is arguably a good thing, reducing overheads and whatnot. In case you still want to use LINQ'isms to operate against such a source, the Task<List<T>> can easily be flattened into an IObservable<T> (e.g. using ToObservable and SelectMany). And a sequential looping through batches can be done using Rx's imperative operators (While) or a plain Concat.

    • Edited by Rx team Monday, November 5, 2012 3:51 AM typo
    • Proposed as answer by Rx team Monday, November 5, 2012 4:03 AM
    • Marked as answer by Stephen ClearyMVP Tuesday, November 13, 2012 1:50 PM
    Monday, November 5, 2012 3:51 AM

All replies

  • I'd also like to know. I've found Ix-Async very useful in our production environment at work. It'd be very unfortunate to never see any more work put into it.

    I've seen EF 6.0's beta async stuff doesn't use anything like IAsyncEnumerable, but instead returns Task<List<T>> which obviously won't work very well if you're processing a large amount of data. We need Ix-Async!

    Friday, October 5, 2012 7:26 PM
  • There's no current investment in this area but we'll consider posting an update that works well against .NET 4.5.

    At the same time, we'd like users to think about the chunky/chatty nature of data retrieval for their scenarios. One of the drawbacks of the async enumerator approach is the very chatty one-element-at-a-time nature, which has some performance price. Though things have been improved significantly in the .NET 4.5 RTM final design on await (e.g. bypassing the awaiter continuation, sync ctx, and execution ctx hops in case the operation already completed), the case where every element retrieval is truly asynchronous has still non-negligible overhead in the async method state machine and task awaiters. (In fact, you may want to restructure the code such that you always obtain the next iteration's Task<bool> to await it after processing the current iteration, as to maximize the chance of synchronous completion and reduced awaiter hoops.) Rx's overhead for element-by-element retrieval is far less (just virtual method calls), but is push-based.

    Most likely, a pull-based async enumeration will ultimately use a data retrieval source that's not as chatty as it seems (e.g. database readers often send multi-record buffers to the client). Reflecting this batchy nature to the layers above is arguably a good thing, reducing overheads and whatnot. In case you still want to use LINQ'isms to operate against such a source, the Task<List<T>> can easily be flattened into an IObservable<T> (e.g. using ToObservable and SelectMany). And a sequential looping through batches can be done using Rx's imperative operators (While) or a plain Concat.

    • Edited by Rx team Monday, November 5, 2012 3:51 AM typo
    • Proposed as answer by Rx team Monday, November 5, 2012 4:03 AM
    • Marked as answer by Stephen ClearyMVP Tuesday, November 13, 2012 1:50 PM
    Monday, November 5, 2012 3:51 AM
  • Big thanks for the reply!

    I do agree chunkiness is important for maximum throughput. I've long considered a set of extensions which operates natively on IAsyncEnumerable<IList<T>>, but there are so many operators to implement that the task seems daunting.

    Interestingly enough, the new DbDataReader async stuff has no way to chunk results either -- I was pretty disappointed at this so I'm not sure how efficient EF6 will be even while returning Task<List<T>>.

    Wednesday, November 7, 2012 3:41 PM
  • There's no current investment in this area but we'll consider posting an update that works well against .NET 4.5.

    And I noticed yesterday that there's now an Ix-Async package on NuGet. Thank you!
    Saturday, April 6, 2013 6:41 PM