.NET Core 3.0 in IAsyncEnumerable <T> What's the big deal?

C # 8.0 and 3.0, one of the most exciting feature is .NET Core IAsyncEnumerable <T> (i.e. async flow). But what is special about it? We can now use it to do what previously impossible things to do?

In this article, we will learn IAsyncEnumerable <T> What are the challenges to be solved, how to implement it, and why IAsyncEnumerable <T> will replace Task <IEnumerable <T >> In many cases in our own applications.

Perhaps the best proof IAsyncEnumerable <T> is a useful way to look at it when there is no difficulty being faced.

For example, first of all there is such a piece of code, like get all posts by page:

  public async Task<IEnumerable<Post>> GetPagePostsFromLikes(int pageNumber)
        {
            // 实现省略
        }

Then there is another piece of code that calls the code above:

public async Task<IEnumerable<Post>> GetAllPostsFromLikes()
        {
            var allPosts = new List<Post>();

            for (int page = 0; ; page++)
            {
                var posts = await GetPagePostsFromLikes(page);
                if (!posts.Any())
                {
                    return allPosts;
                }
                allPosts.AddRange(posts);
            }
        }

Note that the above method has a problem, we loop over the results of each page and into List <Post>, and finally return the entire result. Suppose there are one hundred million page post on the page, then all these billions of pages page posts need to be loaded before the return value. Obviously very inefficient.

Maybe we can not use Task to replace the above method:

public IEnumerable<Post> GetAllPostsFromLikes()
        {
            for (int page = 0; ; page++)
            {
                var posts = GetPagePostsFromLikes(page).GetAwaiter().GetResult();
                if (!posts.Any())
                {
                    yield break;
                }
                foreach (var post in posts)
                {
                    yield return post;
                }
            }
        }

In the above code, return IEnumerable <T> method can be used to yield return statement for each piece of data returned to the caller.

However, do not do it! The above code means that if we call the third function from an asynchronous method, the thread pool will continue iteration IEnumerable return until it is completed, that is when there is a sufficient number of concurrent access to the same thread, it is bound to cause obstruction.

 If we can use asynchronous method to use yield return just fine! Unfortunately, it is impossible ...... until now.

 This time IAsyncEnumerable <T> in respect of appearance it! ! ! ! ! !

IAsyncEnumerable <T> is introduced in the .NET Core 3 (.NET Standard 2.1). Which discloses an enumerator having the enumerator can wait MoveNextAsync () method. This means that producers can make asynchronous calls between produce results.

And return to the task <IEnumerable <T >> different, our approach can now return IAsyncEnumerable <T>, and transmitting data using yield return:

public async IAsyncEnumerable<Post> GetAllPostsFromLikes()
        {
            for (int page = 0; ; page++)
            {
                var posts = GetPagePostsFromLikes(page).GetAwaiter().GetResult();
                if (!posts.Any())
                {
                    yield break;
                }
                foreach (var post in posts)
                {
                    yield return post;
                }
            }
        }

In order to use the results, we need to use c # 8 in New await foreach () syntax:

await foreach (var post in postsRepository.GetAllPostsFromLikes())
            {
                Console.WriteLine(post);
            }

This is much better. The method of generating data is available. Calling code at your own pace using the data.

 

, ASP.NET will be able to return IAsyncEnumerable <T> start from .NET Core API 3.0 Preview 7 from controller action, which means we can return a direct result of the method - the effective flow HTTP response data from the database.

            [HttpGet]
        public IAsyncEnumerable<Post> Get()
    => postsRepository.GetAllPostsFromLikes();

Over time, with the development of .NET Core3.0 and .NET Standard2.1, we will see IAsyncEnumerable <T> is used in the IEnumerable <T >> where we typically use Task <.

to sum up

IAsyncEnumerable <T> is a. NET very popular new properties, in many cases, it can make the code more compact and more efficient.

To learn more, please refer to the following resources:

Guess you like

Origin www.cnblogs.com/yixuanhan/p/11691303.html