-
-
Save DCCoder90/d358ace7ef36401dd6f0449d4ab87706 to your computer and use it in GitHub Desktop.
public static class AsyncEnumerableExtensions | |
{ | |
public static IAsyncEnumerable<TResult> SelectAsync<T, TResult>(this IEnumerable<T> enumerable, | |
Func<T, Task<TResult>> selector) | |
{ | |
return AsyncEnumerable.CreateEnumerable(() => | |
{ | |
var enumerator = enumerable.GetEnumerator(); | |
var current = default(TResult); | |
return AsyncEnumerable.CreateEnumerator(async c => | |
{ | |
var moveNext = enumerator.MoveNext(); | |
current = moveNext | |
? await selector(enumerator.Current).ConfigureAwait(false) | |
: default(TResult); | |
return moveNext; | |
}, | |
() => current, | |
() => enumerator.Dispose()); | |
}); | |
} | |
} |
I mean @DCCoder90 might be using extension methods but its possible to use the above nuget package to get the same results you can also use System.Collections.Generic.AsyncEnumerator.Create.
@masaab that method takes different parameters.
A quicky the System.Collections.Generic.AsyncEnumerator.Create take 3 arguments 1. A Func of movenext, 2. A Func of Current, 3. A Func of Dispose. Its same as @DCCoder90 CreateEnumerable.
If you need another example you could follow the example in the link https://www.nuget.org/packages/AsyncEnumerator/ it is not usingSystem.Collections.Generic.AsyncEnumerator.Create but the example is much cleaner.
@MelbourneDeveloper This was using an Ix.net extension method. More details may be found at
https://stu.dev/iasyncenumerable-introduction/
However this is fairly old currently and would be best to use alternative methods. I would recommend using the approach @masaab mentioned above.
This worked for me
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IEnumerable<T> enumerable)
{
foreach(var item in enumerable)
{
yield return await Task.FromResult(item);
}
}
Ok. Well the above only works if you can use c# 8. If not you can do this:
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace YourCoolNamespace
{
public static class AsyncEnumerableExtensions
{
public static IAsyncEnumerable<T> ToAsyncEnumerable<T>(IEnumerable<T> enumerable) =>
new SynchronousAsyncEnumerable<T>(enumerable);
private class SynchronousAsyncEnumerable<T> : IAsyncEnumerable<T>
{
private readonly IEnumerable<T> _enumerable;
public SynchronousAsyncEnumerable(IEnumerable<T> enumerable) =>
_enumerable = enumerable;
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default) =>
new SynchronousAsyncEnumerator<T>(_enumerable.GetEnumerator());
}
private class SynchronousAsyncEnumerator<T> : IAsyncEnumerator<T>
{
private readonly IEnumerator<T> _enumerator;
public T Current => _enumerator.Current;
public SynchronousAsyncEnumerator(IEnumerator<T> enumerator) =>
_enumerator = enumerator;
public ValueTask DisposeAsync() =>
new ValueTask(Task.CompletedTask);
public ValueTask<bool> MoveNextAsync() =>
new ValueTask<bool>(Task.FromResult(_enumerator.MoveNext()));
}
}
}
You can do it like this with System.Linq.Async
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TestProject3
{
public static class AsyncExtensions
{
public static IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IEnumerator<T> enumerator)
=>
AsyncEnumerable.Create((cancellationToken)
=> AsyncEnumerator.Create(
() => new ValueTask<bool>(enumerator.MoveNext()),
() => enumerator.Current,
() => new ValueTask())
);
}
}
But in AsyncEnumerable
in System.Linq.Async
there already is a ToAsyncEnumerable
function.
https://github.com/dotnet/reactive/blob/main/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToAsyncEnumerable.cs
Well, glad to know I was on the right track. If that's the case, why did this gist come up when I Googled for this?
Well, glad to know I was on the right track. If that's the case, why did this gist come up when I Googled for this?
AFAIK Google doesn't index GitHub repos directly because source code changes too frequently, but it does index Gists which are relatively static.
Consider updating the git description with a "TL&DR: use System.Linq.Async's ToAsyncEnumerable()"
Personally I thought it'd be called AsAsyncEnumerable() and turned to Google after that didn't exist.
@masaab same issue.
There is no
CreateEnumerator
method