Skip to content

[Breaking change]: System.Linq.AsyncEnumerable in .NET 10 #44886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 of 3 tasks
stephentoub opened this issue Feb 13, 2025 · 2 comments · Fixed by #44989 or #45775
Closed
1 of 3 tasks

[Breaking change]: System.Linq.AsyncEnumerable in .NET 10 #44886

stephentoub opened this issue Feb 13, 2025 · 2 comments · Fixed by #44989 or #45775
Assignees
Labels
breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 10 Work items for the .NET 10 release 📌 seQUESTered Identifies that an issue has been imported into Quest.

Comments

@stephentoub
Copy link
Member

stephentoub commented Feb 13, 2025

Description

.NET 10 now includes the AsyncEnumerable class, which provides a full set of Language Integrated Query (LINQ) extension methods for the IAsyncEnumerable<T> type. The System.Linq.Async NuGet library, although it sports a "System." prefix, was written and maintained by the community. This library is being replaced by the new built-in support in .NET 10, in part at the behest of the maintainers of System.Linq.Async. As a result, applications that currently reference the System.Linq.Async package may get compilation errors about ambiguities, due to extension methods with the same signatures being provided both by the old System.Linq.Async library and by the built-in support.

Version

.NET 10 Preview 1

Previous behavior

An AsyncEnumerable class in the System.Linq.Async package provides LINQ support for IAsyncEnumerable<T>.

New behavior

An AsyncEnumerable class in .NET 10 as well as in a System.Linq.AsyncEnumerable nuget package provides LINQ support for IAsyncEnumerable<T>.

Type of breaking change

  • Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
  • Behavioral change: Existing binaries might behave differently at run time.

Reason for change

IAsyncEnumerable<T> has become core enough that it's important the platform itself provide LINQ support for the type. A swell of community support, including from the current maintainers of System.Linq.Async, petitioned for inclusion of such LINQ support directly in the platform.

Recommended action

If the consuming code being upgraded to .NET 10 includes a direct package reference to System.Linq.Async, remove that package reference. If the code needs to multitarget, such that it needs to compile for both .NET 10 and for previous versions of .NET, add a package reference to System.Linq.AsyncEnumerable instead.

If System.Linq.Async is being consumed indirectly via a dependency on another package that depends on System.Linq.Async, and that indirect dependency is leading to similar ambiguity errors, they can be avoided by including this in the project:

<PackageReference Include="System.Linq.Async" Version="6.0.1">
  <ExcludeAssets>all</ExcludeAssets>
</PackageReference>

Most consuming code will not need to change. However, some call sites might need updating to refer to newer names and signatures for functionality.

Feature area

Core .NET libraries

Affected APIs

System.Linq.AsyncEnumerable


Associated WorkItem - 373407

@stephentoub stephentoub added the breaking-change Indicates a .NET Core breaking change label Feb 13, 2025
@dotnet-policy-service dotnet-policy-service bot added the ⌚ Not Triaged Not triaged label Feb 13, 2025
@gewarren gewarren assigned CamSoper and unassigned gewarren Feb 13, 2025
@CamSoper CamSoper added 🏁 Release: .NET 10 Work items for the .NET 10 release and removed ⌚ Not Triaged Not triaged labels Feb 13, 2025
@dotnetrepoman dotnetrepoman bot added the 🗺️ mapQUEST Only used as a way to mark an issue as updated for quest. RepoMan should instantly remove it. label Feb 13, 2025
@dotnet-policy-service dotnet-policy-service bot removed the 🗺️ mapQUEST Only used as a way to mark an issue as updated for quest. RepoMan should instantly remove it. label Feb 13, 2025
@CamSoper CamSoper added 🗺️ reQUEST Triggers an issue to be imported into Quest. 🗺️ mapQUEST Only used as a way to mark an issue as updated for quest. RepoMan should instantly remove it. labels Feb 13, 2025
@dotnet-policy-service dotnet-policy-service bot removed the 🗺️ mapQUEST Only used as a way to mark an issue as updated for quest. RepoMan should instantly remove it. label Feb 13, 2025
@sequestor sequestor bot added 📌 seQUESTered Identifies that an issue has been imported into Quest. and removed 🗺️ reQUEST Triggers an issue to be imported into Quest. labels Feb 14, 2025
@CamSoper CamSoper moved this from 🔖 Ready to 🏗 In progress in dotnet/docs February 2025 sprint project Feb 21, 2025
@dotnet-policy-service dotnet-policy-service bot added the in-pr This issue will be closed (fixed) by an active pull request. label Feb 21, 2025
@CamSoper CamSoper moved this from 🏗 In progress to 👀 In review in dotnet/docs February 2025 sprint project Feb 25, 2025
@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in dotnet/docs February 2025 sprint project Feb 25, 2025
@eiriktsarpalis
Copy link
Member

Reopening so that details regarding this request can be added.

@eiriktsarpalis eiriktsarpalis reopened this Apr 8, 2025
@dotnet-policy-service dotnet-policy-service bot added the ⌚ Not Triaged Not triaged label Apr 8, 2025
@CamSoper CamSoper removed ⌚ Not Triaged Not triaged in-pr This issue will be closed (fixed) by an active pull request. labels Apr 8, 2025
@dotnetrepoman dotnetrepoman bot added the 🗺️ mapQUEST Only used as a way to mark an issue as updated for quest. RepoMan should instantly remove it. label Apr 8, 2025
@dotnet-policy-service dotnet-policy-service bot removed the 🗺️ mapQUEST Only used as a way to mark an issue as updated for quest. RepoMan should instantly remove it. label Apr 8, 2025
@CamSoper CamSoper moved this from 🔖 Ready to 🏗 In progress in dotnet/docs April 2025 sprint project Apr 10, 2025
CamSoper added a commit to CamSoper/dotnet.docs that referenced this issue Apr 10, 2025
@github-project-automation github-project-automation bot moved this from 🏗 In progress to ✅ Done in dotnet/docs April 2025 sprint project Apr 11, 2025
@CamSoper
Copy link
Contributor

CamSoper commented Apr 11, 2025

@eiriktsarpalis At the time the original breaking change was published, we didn't have the API documented so we couldn't include XREFs. Those have been added, liberally, to answer the first part of the request asking for the details of what's included in the new library.

Regarding the rest of the request, it appears there is no documentation available for System.Linq.Async. Consequently, I don't have any way of establishing a delta between System.Linq.Async and the new API without writing samples to test every overload of every method. This will also require me to familiarize myself with IAsyncEnumerable, which I haven't worked with much.

I thought @stephentoub's recommendations were pretty clear, but what else can we provide here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 10 Work items for the .NET 10 release 📌 seQUESTered Identifies that an issue has been imported into Quest.
Projects
4 participants