linvi / tweetinvi

Tweetinvi, an intuitive Twitter C# library for the REST and Stream API. It supports .NET, .NETCore, UAP (Xamarin)...
MIT License
1.01k stars 220 forks source link

Iterators and IAsyncEnumerable<T> #1085

Open WorldMaker opened 4 years ago

WorldMaker commented 4 years ago

Since C# added direct support for IAsyncEnumerable<T> (and the System.Interactive extensions provide a lot of useful high-level "LINQ" functionality on top of it), it makes a lot of sense to directly project the ITwitterIterator<T, U> to IAsyncEnumerable<T>. I implemented very simply in an extension method of my own, but it might be something useful to add directly to the Iterators themselves (and possibly may be slightly more efficient in some cases to do so, albeit I have not looked directly at Iterator source code to verify this possibility).

Here's my very simple extension methods as example/demonstration:

    public static class TweetinviExtensions
    {
        public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(this Tweetinvi.Iterators.ITwitterIterator<T> iterator)
        {
            while (!iterator.Completed)
            {
                foreach (var item in await iterator.NextPageAsync())
                {
                    yield return item;
                }
            }
        }

        public static async IAsyncEnumerable<T> ToAsyncEnumerable<T, U>(this Tweetinvi.Iterators.ITwitterIterator<T, U> iterator)
        {
            while (!iterator.Completed)
            {
                foreach (var item in await iterator.NextPageAsync())
                {
                    yield return item;
                }
            }
        }
    }
linvi commented 4 years ago

Thanks for sharing, I am not yet aware of the benefit of the IAsyncEnumerable but I will definitely look into it.

WorldMaker commented 3 years ago

No rush. In a quick nutshell, if it helps: IAsyncEnumerable<T> is when IEnumerable<T> and Task<T> joined forces, and just as System.Linq provides a bunch of useful operations on top of IEnumerable<T> there are libraries like System..Linq.Async (in the NuGet package System.Interactive.Async) which provide all of the same operators and more. The C# compiler also supports them in the ability to build async generator functions (using the yield return keyword in an async marked function), which is why the example extension methods are so small, because just like IEnumerable<T> generator functions and async functions with Task<T>, C# does a lot of useful boring plumbing for you. (That's where some of the most likely benefits may be to writing the Iterators more directly as IAsyncEnumerable<T> where an async generator function makes sense and cleans up the code.)