Start Debugging

.NET 11 Runtime Async отказывается от флага EnablePreviewFeatures

По мере того как предварительные версии .NET 11 приближаются к ноябрьскому выпуску, Runtime Async повзрослел: проекты net11.0 включают его одним свойством MSBuild, а сами библиотеки среды выполнения теперь компилируются с ним.

Когда Runtime Async впервые появился в .NET 11 Preview 2, для его включения требовались два свойства MSBuild и явное признание того, что вы работаете на грани возможного. По мере того как предварительные версии приближались к выпуску в ноябре 2026 года (Preview 6 вышел 10 июля), этот барьер тихо исчез. Runtime Async по-прежнему остаётся функцией в предварительной версии, но проекту net11.0 больше не нужно <EnablePreviewFeatures>true</EnablePreviewFeatures>, чтобы использовать его, а сами библиотеки среды выполнения .NET теперь компилируются с ним.

Одно свойство вместо двух

Если вы следовали первоначальной статье о Runtime Async, ваш .csproj выглядел так:

<PropertyGroup>
  <Features>runtime-async=on</Features>
  <EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>

Теперь для включения нужен только флаг компилятора:

<PropertyGroup>
  <Features>runtime-async=on</Features>
</PropertyGroup>

EnablePreviewFeatures подтягивал всю поверхность анализатора System.Runtime.Experimental и помечал ваш проект как участвующий во всех предварительных API из SDK. Его удаление означает, что вы можете попробовать нативный для среды выполнения async, не давая случайно зелёный свет несвязанным экспериментальным функциям во всей сборке.

BCL теперь использует это в собственном коде

Более важный сигнал в том, что библиотеки среды выполнения .NET компилируются с runtime-async=on. Они больше не содержат сгенерированных компилятором конечных автоматов и полностью полагаются на async, предоставляемый средой выполнения. Каждый await, который вы делаете в сторону System.Net.Http, System.IO или System.Text.Json, уже выполняется на новой модели. Это даёт функции широкую функциональную проверку и проверку производительности до того, как она станет вариантом по умолчанию, и означает, что приложение, единственными асинхронными зависимостями которого являются библиотеки фреймворка, на практике уже переведено.

Переключатели, изменившиеся незаметно

Если у вас были скрипты или профили запуска, обращавшиеся к старым переменным среды, их больше нет. Переменные DOTNET_RuntimeAsync и UNSUPPORTED_RuntimeAsync, которые раньше переключали поведение, удалены. Чтобы теперь отключить конкретный проект, задайте вместо этого свойство проекта:

<PropertyGroup>
  <UseRuntimeAsync>false</UseRuntimeAsync>
</PropertyGroup>

Более широкий охват компиляции

Два исправления расширяют область, где Runtime Async действительно применяется. Ковариантные переопределения Task в Task<T> теперь работают: когда производный класс возвращает Task<T> для базового метода, типизированного как Task, среда выполнения генерирует возвращающий void thunk, который сглаживает разницу в соглашении о вызовах, так что виртуальная диспетчеризация работает для обоих вариантов, в том числе под NativeAOT. А ограничение, которое мешало встраиванию (inline) методов runtime-async во время компиляции ReadyToRun (crossgen2), снято, поэтому синхронный быстрый путь async-метода без await может быть встроен от начала до конца.

Ничто из этого пока не делает Runtime Async вариантом по умолчанию для продакшена. Но усилие, необходимое, чтобы попробовать его на реальной кодовой базе .NET 11, теперь сводится к одной строке MSBuild, а стандартная библиотека уже служит доказательством того, что он держится. Все подробности о включении есть на странице Что нового в среде выполнения .NET 11.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад