<PackageReference Include="AsyncEnumerator" Version="2.2.0" />

AsyncEnumerator 2.2.0

Introduces IAsyncEnumerable, IAsyncEnumerator, ForEachAsync(), and ParallelForEachAsync() GitHub: https://github.com/tyrotoxin/AsyncEnumerable PROBLEM SPACE Helps to (a) create an element provider, where producing an element can take a lot of time due to dependency on other asynchronous events (e.g. wait handles, network streams), and (b) a consumer that processes those element as soon as they are ready without blocking the thread (the processing is scheduled on a worker thread instead). EXAMPLE using System.Collections.Async; static IAsyncEnumerable<int> ProduceAsyncNumbers(int start, int end) { return new AsyncEnumerable<int>(async yield => { // Just to show that ReturnAsync can be used multiple times await yield.ReturnAsync(start); for (int number = start + 1; number <= end; number++) await yield.ReturnAsync(number); // You can break the enumeration loop with the following call: yield.Break(); // This won't be executed due to the loop break above await yield.ReturnAsync(12345); }); } // Just to compare with synchronous version of enumerator static IEnumerable<int> ProduceNumbers(int start, int end) { yield return start; for (int number = start + 1; number <= end; number++) yield return number; yield break; yield return 12345; } static async Task ConsumeNumbersAsync() { var asyncEnumerableCollection = ProduceAsyncNumbers(start: 1, end: 10); await asyncEnumerableCollection.ForEachAsync(async number => { await Console.Out.WriteLineAsync($"{number}"); }); } // Just to compare with synchronous version of enumeration static void ConsumeNumbers() { var enumerableCollection = ProduceNumbers(start: 1, end: 10); foreach (var number in enumerableCollection) { Console.Out.WriteLine($"{number}"); } }

<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
  <metadata>
    <id>AsyncEnumerator</id>
    <version>2.2.0</version>
    <authors>Serge Semenov</authors>
    <licenseUrl>https://opensource.org/licenses/MIT</licenseUrl>
    <projectUrl>https://github.com/tyrotoxin/AsyncEnumerable</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Introduces IAsyncEnumerable, IAsyncEnumerator, ForEachAsync(), and ParallelForEachAsync()
GitHub: https://github.com/tyrotoxin/AsyncEnumerable

PROBLEM SPACE

Helps to (a) create an element provider, where producing an element can take a lot of time
due to dependency on other asynchronous events (e.g. wait handles, network streams), and
(b) a consumer that processes those element as soon as they are ready without blocking
the thread (the processing is scheduled on a worker thread instead).


EXAMPLE

using System.Collections.Async;

static IAsyncEnumerable&lt;int&gt; ProduceAsyncNumbers(int start, int end)
{
  return new AsyncEnumerable&lt;int&gt;(async yield =&gt; {

    // Just to show that ReturnAsync can be used multiple times
    await yield.ReturnAsync(start);

    for (int number = start + 1; number &lt;= end; number++)
      await yield.ReturnAsync(number);

    // You can break the enumeration loop with the following call:
    yield.Break();

    // This won't be executed due to the loop break above
    await yield.ReturnAsync(12345);
  });
}

// Just to compare with synchronous version of enumerator
static IEnumerable&lt;int&gt; ProduceNumbers(int start, int end)
{
  yield return start;

  for (int number = start + 1; number &lt;= end; number++)
    yield return number;

  yield break;

  yield return 12345;
}

static async Task ConsumeNumbersAsync()
{
  var asyncEnumerableCollection = ProduceAsyncNumbers(start: 1, end: 10);
  await asyncEnumerableCollection.ForEachAsync(async number =&gt; {
    await Console.Out.WriteLineAsync($"{number}");
  });
}

// Just to compare with synchronous version of enumeration
static void ConsumeNumbers()
{
  var enumerableCollection = ProduceNumbers(start: 1, end: 10);
  foreach (var number in enumerableCollection) {
    Console.Out.WriteLine($"{number}");
  }
}</description>
    <summary>Introduces IAsyncEnumerable, IAsyncEnumerator, ForEachAsync(), and ParallelForEachAsync()</summary>
    <releaseNotes>2.2.0: New extension methods: SelectMany, Append, Prepend, OfType, Concat, Distinct, ToDictionaryAsync, ToLookupAsync, AggregateAsync.
2.1.0: New extension methods: Batch, UnionAll, Single, SingleOrDefault, DefaultIfEmpty, Cast.
2.0.0: Revise design of the library: same features, but slight paradigm shift and interface breaking changes.
1.5.0: Add support for .NET Standard, minor improvements.
1.4.2: Add finalizer to AsyncEnumerator and call Dispose in ForEachAsync and ParallelForEachAsync extension methods.
1.4.0: Add new generic type AsyncEnumeratorWithState for performance optimization.
       Now IAsyncEnumerator&lt;T&gt; is covariant.
       Add ForEachAsync, ParallelForeachAsync, and LINQ-style extension methods for IAsyncEnumerator.
1.2.1: New Linq-style extension methods in System.Collections.Async namespace.
1.1.0: Add ParallelForEachAsync extension methods for IEnumerable&lt;T&gt; and IAsyncEnumerable&lt;T&gt; in System.Collections.Async namespace.</releaseNotes>
    <tags>IAsyncEnumerable IAsyncEnumerator ForEachAsync ParallelForEachAsync async await foreach parallel</tags>
  </metadata>
</package>