-
-
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()); | |
}); | |
} | |
} |
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.
@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.