{"id":4321,"date":"2020-12-01T09:30:43","date_gmt":"2020-12-01T08:30:43","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=4321"},"modified":"2022-09-06T08:10:44","modified_gmt":"2022-09-06T07:10:44","slug":"c-iasyncenumerable","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/c-iasyncenumerable\/","title":{"rendered":"C# IAsyncEnumerable<T>"},"content":{"rendered":"\n<p>Source: <a href=\"https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/web-api\/action-return-types?view=aspnetcore-5.0\">https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/web-api\/action-return-types?view=aspnetcore-5.0<\/a><\/p>\n\n\n\n<p>&nbsp;ASP.NET Core 3.0 and later, returning&nbsp;<code>IAsyncEnumerable&lt;T&gt;<\/code>&nbsp;from an action:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>No longer results in synchronous iteration.<\/li><li>Becomes as efficient as returning&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.collections.generic.ienumerable-1\">IEnumerable&lt;T&gt;<\/a>.<\/li><\/ul>\n\n\n\n<p>ASP.NET Core 3.0 and later buffers the result of the following action before providing it to the serializer:C#Copy<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public IEnumerable&lt;Product> GetOnSaleProducts() =>\n    _context.Products.Where(p => p.IsOnSale);\n<\/pre>\n\n\n\n<p>Consider declaring the action signature&#8217;s return type as&nbsp;<code>IAsyncEnumerable&lt;T&gt;<\/code>&nbsp;to guarantee the asynchronous iteration. Ultimately, the iteration mode is based on the underlying concrete type being returned. MVC automatically buffers any concrete type that implements&nbsp;<code>IAsyncEnumerable&lt;T&gt;<\/code>.<\/p>\n\n\n\n<p>Consider the following action, which returns sale-priced product records as&nbsp;<code>IEnumerable&lt;Product&gt;<\/code>:C#Copy<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[HttpGet(\"syncsale\")]\npublic IEnumerable&lt;Product> GetOnSaleProducts()\n{\n    var products = _repository.GetProducts();\n\n    foreach (var product in products)\n    {\n        if (product.IsOnSale)\n        {\n            yield return product;\n        }\n    }\n}\n<\/pre>\n\n\n\n<p>The&nbsp;<code>IAsyncEnumerable&lt;Product&gt;<\/code>&nbsp;equivalent of the preceding action is:C#Copy<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[HttpGet(\"asyncsale\")]\npublic async IAsyncEnumerable&lt;Product> GetOnSaleProductsAsync()\n{\n    var products = _repository.GetProductsAsync();\n\n    await foreach (var product in products)\n    {\n        if (product.IsOnSale)\n        {\n            yield return product;\n        }\n    }\n}\n<\/pre>\n\n\n\n<p>Both of the preceding actions are non-blocking as of ASP.NET Core 3.0.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/web-api\/action-return-types?view=aspnetcore-5.0 &nbsp;ASP.NET Core 3.0 and later, returning&nbsp;IAsyncEnumerable&lt;T&gt;&nbsp;from an action: No longer results in synchronous iteration. Becomes as efficient as returning&nbsp;IEnumerable&lt;T&gt;. ASP.NET Core 3.0 and later buffers the result of the following action before providing it to the serializer:C#Copy Consider declaring the action signature&#8217;s return type as&nbsp;IAsyncEnumerable&lt;T&gt;&nbsp;to guarantee the asynchronous iteration. Ultimately, the iteration mode [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[6,4,1],"tags":[],"class_list":["post-4321","post","type-post","status-publish","format-standard","hentry","category-dotnet","category-programming","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/4321","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=4321"}],"version-history":[{"count":3,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/4321\/revisions"}],"predecessor-version":[{"id":6664,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/4321\/revisions\/6664"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=4321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=4321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=4321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}