June 10th, 2024

.NET Build 2024:引领AI与云原生应用开发的新篇章

Amy Peng
Partner Tech Advisor

本文翻译自.NET Team的.NET Announcements and Updates from Microsoft Build 2024 – .NET Blog

Microsoft Build 2024 上,我们很高兴推出一系列旨在使 .NET 开发更快、更容易的新功能和工具  

探索 Microsoft Build 2024 上的 .NET 会议,了解新功能的实际效果,或者通过下 .NET 9 Preview 4 亲自尝试 

Image build dotnet overview

以下是我们的更新和公告: 

  • 人工智能用于构建AI应用的端到端方案、拥抱AI生态、与云服务深度集成 
  • .NET Aspire:用于构建云原生分布式应用程序,今天发布。 
  • C# 13加强了许多深受喜爱的 C# 功能,使它们更适合您 
  • 性能:通过关键基准测试减少内存和执行时间。 

让我们从如何使用 .NET 为开发人员改进 AI 开发开始 

.NET 与人工智能 

.NET 为您提供了使用 AI 创建功能强大的应用程序的工具。您可以使用Semantic Kernel来编排 AI 插件,从而将 AI 功能无缝集成到您的应用程序中。您可以使用最先进的库(例如 OpenAI、Qdrant Milvus)来增强应用程序的功能。您还可以使用 .NET Aspire 将应用程序部署到云端,确保最佳性能和可扩展性。 让我们更深入地了解这些内容 

Image build ai investments

AI基础知识 

我们引入了一种新的 Tensor<T> 类型。张量是许多数学模型的基本组成部分,包括深度学习算法。它们是用于保存神经网络中的权重、偏差和中间计算的多维数组这样可以有效的处理数据和信息流,以用于学习和预测目的无论是图像识别、语言理解还是趋势预测,张量在AI的各个方面都发挥着至关重要的作用。 此外,它们还可以更轻松地在 ONNX Runtime、TorchSharp ML.NET 等库之间共享数据、创建自己的数学库或使用 AI 模型开发应用程序。 性能是关键,我们通过构建 TensorPrimitives(利用 SIMD 指令来优化吞吐量)来实现额外的效率 

我们很高兴看到您使用 Tensor<T>,请尝试一下并向我们提供反馈 

快速开始构建 AI 应用程序 

AI的世界正在快速发展,我们确保开发人员只需对代码进行最小的更改即可快速入门。 请尝试一下我们新的 AI 快速入门示例,了解如何开始使用 Semantic Kernel LLM 框架来快速进入 AI 生态系统。 Semantic Kernel允许开发人员利用各种模型,连接到矢量存储,并使用模板简化其提示过程 

除了我们的示例之外,我们还在开发智能组件即专为 Blazor MVC / Razor 设计的具有端到端 AI 功能的预构建控件。 这些组件可以在几分钟内集成您现有的应用程序中,为它们注入AI功能。 借助智能组件,团队可以节省大量开发时间,无需进行广泛的用户体验设计或对机器学习和提示工程进行深入研究目前,我们有三个可以集成的智能组件,包括:SmartPasteButton、SmartTextArea SmartComboBox。 以下是添加 SmartPasteButton 的示例,它从剪贴板获取复制文本并使用 AI 自动填充 InputText 控件 

@page "/"
@using SmartComponents

<form>
    <p>Name: <InputText @bind-Value="@name" /></p>
    <p>Address line 1: <InputText @bind-Value="@addr1" /></p>
    <p>City: <InputText @bind-Value="@city" /></p>
    <p>Zip/postal code: <InputText @bind-Value="@zip" /></p>

    <button type="submit">Submit</button>
    <SmartPasteButton DefaultIcon />
</form>

@code {
    string? name, addr1, city, zip;
}

以下是如何使用智能组件将剪贴板中的数据直接智能地粘贴到表单中 

Image build smart components 

扩展 .NET AI 生态系统 

我们与Microsoft和整个行业的众多合作伙伴合作,帮助开发人员能够充分利用AI的生态系统。 今年我们最激动人心的合作之一是与 OpenAI 的合作。 我们与他们合作推出了一个官方 .NET 库,该库将于本月晚些时候发布。 此次合作和新的SDK 确保 .NET 开发人员获得愉快的体验,并与您可能熟悉的其他编程语言库相媲美。它还支持最新的 OpenAI 功能和模型,例如 GPT4o Assistants v2,以及跨 OpenAI Azure OpenAI 的统一体验。 请加入我们的 .NET OpenAI SDK 顾问团队以便对此SDK的发展产生影响 

我们的合作不止于此。去年,我们宣布与 Qdrant Milivus 合作,推出了官方的C#客户端。我们将继续与 Weavite 等合作伙伴合作,为开发人员提供各种 .NET 矢量数据库选项最后,我们一直与 Microsoft 的团队合作,包括 Semantic Kernel、Azure SQL Azure AI Search,以确保我们的开发人员能够利用其 AI 功能获得无缝的本机体验 

未来投资:监控和观察您的 LLM 应用程序。 

大型语言模型 (LLM) 应用程序需要可靠、高性能和高质量的结果。 开发人员需要在开发和生产环境中测量和跟踪LLM 应用程序的结果和行为,并识别和解决任何问题 

我们的团队正在研究开发人员如何使用 .NET AspireSemantic Kernel Azure 来监控他们的 AI 应用程序。 这些功能目前处于预览阶段,我们欢迎您的反馈。 下图演示了如何使用 .NET Aspire 以最少的代码从Semantic Kernel收集详细的指标和跟踪数据,例如模型、令牌计数、提示和生成的响应,遵循当前正在设计的 LLM OpenTelemetry 标准约定 

开发人员可以使用 .NET Aspire 查看开发中的这些跟踪,并使用 App Insights 等各种 Azure Monitor 工具查看生产中的这些跟踪。 以下是在 .NET Aspire App Insights 中启用跟踪的示例 

Image build aspire ai telemetry scaled

我们只需几行代码就可以使用Semantic Kernel轻松收集遥测数据 

// Enable the draft OpenTelemetry LLM data to be collected
AppContext.SetSwitch("Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnosticsSensitive", true);

// Export the data
builder.Services.AddOpenTelemetry()
   .WithMetrics(m => m.AddMeter("Microsoft.SemanticKernel*"))
   .WithTracing(t => t.AddSource("Microsoft.SemanticKernel*"));

我们致力于将 .NET 打造成一个出色的平台,用于构建和集成 AI 到您的应用程序中,并与 AI 生态系统中的库以及包括 ASP.NET Core .NET Aspire 在内的出色框架无缝协作,以构建云原生应用程序接下来,让我们更深入地了解我们如何投入精力使用 .NET 构建云原生应用程序 

使用 .NET 进行云原生开发 

使用 .NET,您可以构建安全、高效、灵活、可观察且可配置的云原生应用程序。 我们通过以下方式增强云原生应用程序开发 

  • Chiseled 容器:减小 .NET 容器镜像的大小 
  • NativeAOT Trimming:减少应用程序大小,同时缩短应用程序启动时间 
  • ASP.NET Core 的新功能和库可简化云原生场景。 
  • 性能:充分利用所有框架和库的性能。 

我们将继续努力通过推出 .NET Aspire 并持续投资 .NET 9 的云原生场景来改善开发人员构建这些应用程序的体验。让我们从 .NET Aspire 开始,看看如何在 .NET 应用程序中利用它 

.NET Aspire:简化云原生开发 

.NET Aspire 是一个新的堆栈,可简化 .NET 云原生应用程序和服务的开发。 我们很高兴地宣布 .NET Aspire 现已全面上市 

请通过最新版本的 Visual Studio 2022 (17.10).NET CLI 带有 C# 开发工具包的 Visual Studio Code 开启 .NET Aspire的开发之路。 .NET Aspire 汇集了工具、模板和 NuGet 包,可帮助您更轻松地在 .NET 中构建可观察、分布式、可用于生产的应用程序。 无论您是构建新应用程序、向现有应用程序添加云原生功能,还是已经将 .NET 应用程序部署到云中的生产环境,.NET Aspire 都可以帮助您更快地实现目标 

.NET Aspire 支持构建分布式应用程序,包括项目编排、与重要服务和平台集成的组件、服务发现、服务默认值等等。 

.NET Aspire 的一个主要亮点是仪表板,它提供了应用程序资源的综合视图,包括日志、分布式跟踪和指标。 无论是在本地开发人员内循环期间运行还是部署在云中,仪表板都提供了以开发人员为中心的实时视图,显示您的应用程序当前正在执行的操作 

下图显示了从前端 Web 应用程序到多个依赖的后端服务、缓存和数据库的跟踪 

Image build aspire dashboard build

开发人员需要在整个开发过程中部署分布式应用程序以进行快速测试,并且需要能够在需要时轻松部署到生产中。.NET Aspire 在此时可以提供帮助 ,它具有强大的功能,可将应用程序迁移到云端,支持在开发期间配置和连接到 Azure AWS 中的云服务,并使用 Azure 开发者 CLI 或带有 Aspirate Kubernetes 将应用程序部署到 Azure 容器应用程序 

Image build aspire overview

.NET Linux 原生的 

.NET 是跨平台的。我们的使命是确保 .NET 在开发人员构建应用程序的任何地方都能出色运行 🚀。我们投入大量资源来提升开发人员同时改善在 Linux 上运行的应用程序的生产工作流程 

我们与 Canonical、Red Hat 和其他维护者合作,确保 .NET 软件包可以从官方源安装,并按照与 Microsoft 相同的时间表更新安全补丁 

例如,.NET 8 Ubuntu 24.04 中可用,可使用以下命令安装 

sudo apt update
sudo apt install dotnet

容器是部署云原生应用程序最流行的方式。 容器越小,配置新节点的速度就越快。 较小的镜像通常也更安全。 Chiseled 容器是解决此问题的方法,它们现在通常可用于 .NET 8 .NET 9 Ubuntu 24.04。备受期待的全球化友好型镜像现已推出,其中包括 icu tzdata  

让我们看看 chiseled 镜像对 ASP.NET Core Web 应用程序的影响。Ubuntu 24.04 chiseled 镜像比使用常规 Ubuntu 小约 45%。唯一的变化是使用不同的基础镜像 

Image build nobel aspnetcore

 

现在,让我们介绍一些 .NET 9 的新特性和增强功能,您现在就可以尝试这些新功能来优化云原生应用程序 

减少内存使用量 

自动内存管理一直是 .NET 的关键功能,其世界一流的垃圾收集功能针对各种场景进行了优化。对于云原生应用程序开发,我们通过引入新的服务器垃圾收集器 (GC) 模式 .NET 9 提升到了一个新的水平。这种新模式显著减少了内存使用量,从而可以降低成本,同时提供 .NET 所著称的出色性能 

这对云原生应用意味着什么?假设您有一个包含两个节点的 Kubernetes 集群。这项新功能将根据请求规模自适应地响应流量,从而自动在这两个节点中停留更长时间 

让我们看一下新服务器 GC 模式的实际示例。下图显示了 Fortunes TechEmpower 基准测试应用程序在配置了 4 CPU 核心的容器中以每秒 1,000 个请求 (RPS) 的速度运行。现有服务器 GC 模式为蓝色,新服务器 GC 模式为黑色。新模式使用的内存不到三分之一 🤯 

Image build memory usage

10,000 RPS 运行此示例显示了类似的改进。我们的测试表明,新的服务器 GC 模式对其他指标的影响非常小。 

来源:ASP.NET Core 基准测试(容器页面) 

性能是每个 .NET 版本的重点,.NET 9 也不例外。每次发布新版本,人们都会告诉我们,他们的应用程序升级后运行地更快了。这正是我们所希望的!这一次,我们进行了一系列重大更改,让您的应用程序在生产中运行得更快、更精简 

我们很高兴您能在 .NET 运行时中试用这些最新的低级优化,并向我们反馈它们对您的应用的影响。现在,让我们深入了解 C#即将推出的新功能 

C# 13 

C# 13 专注于灵活性和性能,使您喜欢的许多功能变得更加出色。我们正在增强params参数为您提供更多灵活性,使用扩展类型将扩展提升到一个新的水平,并添加了几个功能来增强性能,其中一些功能您可以免费获得,而无需修改代码。让我们来看看吧! 

加强 C# params 

params不再局限于数组! 

params 关键字出现在参数之前时,对该方法的调用可以提供零个或多个值的逗号分隔列表,这些值将放置在参数类型的集合中。从 C# 13 开始,params 参数类型可以是用于集合表达式的任何类型,例如 List<T>、Span<T> IEnumerable<T>。如果它们遵循特殊规则,您甚至可以使用自己的集合类型 

只需指定不同的集合类型作为参数类型: 

void PrintList(params IEnumerable<string> list) 
    => Console.WriteLine(string.Join(", ", list));

PrintList("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");

// prints "Sun, Mon, Tue, Wed, Thu, Fri, Sat"

 

使用最适合您需求的集合类型非常简单。使用您的方法的程序员只需传递逗号分隔的值列表即可。他们无需关心底层类型。 

利用 Span改进params 

性能的一个重要方面是减少内存使用,System.Span<T>System.ReadonlySpan<T>是减少内存分配的工具。您可以在内存和 Span 使用指南中了解更多信息。 

如果您想使用 span,只需将params参数类型转换为 span 类型即可。传递给params参数的值会隐式转换为该 span 类型。如果您有两个方法签名,它们的区别仅在于一个是span,另一个是数组,并且调用代码使用值列表,则将选择 span 重载。这意味着您正在运行最快的代码,并且可以更轻松地将 span 添加到您的应用。 

.NET 运行时的许多方法都被更新为接受params Span<T>,所以即使您不直接使用 span,您的应用程序也会运行得更快。这是我们不断努力使 C# 更快、更可靠的一部分同时也是我们致力于确保各种 C# 功能能够很好地协同工作的一个例子。以下是来自 StringBuilder的一个示例 

public StringBuilder AppendJoin(string? separator, params ReadOnlySpan<string?> values)

params和接口 

有了对接口参数的支持,事情就变得更好了。如果没有指定具体类型,编译器如何知道要使用哪种类型 

就像 C# 12 中的集合表达式一样,当您将接口指定为参数类型时,这清楚地表明您只需要实现该接口的任何东西。关键接口映射到实现,因此我们可以为您提供满足接口的最佳可用类型。编译器可以使用现有类型或创建一个类型。您不应该对底层具体集合类型有任何依赖,因为如果有更好的类型可用,我们会更改它 

这种设计的优点是,您可以只使用接口作为params类型。如果您传递一个实现接口的类型的值,那么就使用这个值。当您传递一个值列表或一个集合表达式时,编译器会为您 

提供最佳的具体类型 

扩展类型 

扩展类型不在当前预览中,但您会在 Mads Torgersen Dustin Campbell 的演讲“C#13中的新功能中看到它们的演示。下面让我们一睹 C# 13 故事中这一重要部分的风采 

C# 3 起,即使您无法更改其代码扩展方法也允许您向底层类型添加方法。 LINQ IEnumerable<T> 上的一组扩展方法的示例。 LINQ 扩展方法看起来就像是底层类型上的实例方法 

C# 13 在扩展类型方面迈出了下一步。 这是一种为底层类型提供扩展成员的新类型。 它们具有方法、属性和其他可以是实例或静态的成员。 实例扩展类型无法保存状态。 例如,它们不能包含字段。 它们可以访问底层类型或其他位置的状态 

有两种扩展类型:隐式扩展和显式扩展。 隐式扩展类型适用于所有出现的底层类型——就像现在的扩展方法一样。 显式扩展方法和属性仅适用于已转换为显式扩展类型的底层类型的实例 

扩展类型构建在底层类型之上,这些类型只是普通的 C# 类型。使用扩展的一个原因是您无法更改底层类型的代码。 

让我们看一些示例,从底层类型开始,假设我们无权更改其代码 

public class Person()
{
    public required string GivenName { get; init; } 
    public required string SurName { get; init; }
    public required Organization Organization { get; init; } 
} 

public class Organization()
{
    public required string Name { get; init; }
    public required List<Team> Teams { get; init; }
} 

public class Team()
{
    public required string TeamName { get; init; }
    public required Person Lead { get; init; }
    public required IEnumerable<Person> Members { get; init; }
} 

 

一段 LINQ 代码可以返回某个Person 是否是lead。 由于我们不想每次需要时都编写这段代码,因此我们可以编写一个扩展方法并根据需要通过命名空间控制对它的访问或者,我们可以使用隐式扩展类型来组织 Person 类的扩展,并将 IsLead 作为属性提供给所有 Person 实例 

public implicit extension PersonExtension for Person
{
    public bool IsLead
        => this.Organization
            .Teams
            .Any(team => team. Lead == this);
}

这个属性可以这样调用 

if (person.IsLead) { ... }

显式扩展允许您为类型的特定实例提供额外的功能。 例如,检索某人领导的团队是有意义的显式扩展只能向lead提供 Teams 属性 

public explicit extension Lead for Person
{
    public IEnumerable<Team> Teams 
        => this.Organization
            .Teams
            .Where(team => team. Lead == this);
}

 

隐式和显式扩展类型都支持静态成员和实例成员。使用此功能的一种方法是提供特定于您的场景的默认值。在本例中,我们只有一个组织,每次创建人员时都要指定它,这样做很不方便 

public implicit extension OrganizationExtension for Organization
{
   private static Organization ourOrganization = new Organization("C# Design");

   public static Person CreatePerson(string givenName, string surName) 
       => new(givenName, surName, ourOrganization);
}

把这些放在一起 

var mads = Organization.CreatePerson("Mads", "Torgersen");
// code to add more people and teams
if (mads.IsLead)
{
    Lead madsAsLead = mads;
    PrintReport(madsAsLead.Teams);
}

从使用的角度来看,扩展类型允许您简化提供应用程序的重要工作和逻辑的代码。 它通过组织扩展和提供自定义底层对象的特定实例的扩展来实现这一点。 从技术角度来看,扩展类型是对您当前使用的扩展方法的增强。在C# 13的未来预览版中,您可以尝试使用它们。 

这只是我们正在开发的内容的简要概述,随着功能的完善,您将看到更详细的帖子。要查看我们正在开发的所有功能,请查看 Roslyn 功能状态页面。在 Microsoft Build 上,Mads Torgersen Dustin Campbell 的演讲C# 13 中的新功能中了解有关所有这些功能的更多信息 

使用 .NET 进行 Web 开发 

.NET 包括 ASP.NET Core,它拥有构建现代 Web 应用程序所需的一切,包括基于浏览器的 Web 应用程序或可扩展的后端服务。 使用 .NET,无需将多个不同框架的解决方案拼接在一起。 .NET 专为安全性而构建,并针对性能进行了优化,因此您可以随时处理任何服务器场景。 

Image build full stack web platform

我们将继续改进 .NET ASP.NET Core Web 开发体验。 .NET 9 中,我们专注于解决质量和基础问题,包括性能、安全性和可靠性。 现有的 ASP.NET Core 功能也得到了重要升级,以满足现代云原生应用的需求 

OpenAPI 文档生成的内置支持 

OpenAPI 规范使开发人员能够以标准化格式定义 API 的形式,这些格式可以插入客户端生成器、服务器生成器、测试工具、文档等中。 ASP.NET Core 现在提供内置支持,用于生成表示基于控制器或最小 API OpenAPI 文档 

var builder = WebApplication.CreateBuilder();
builder.Services.AddOpenApi();

var app = builder.Build();
app.MapOpenApi();
app.MapGet("/hello/{name}", (string name) => $"Hello {name}"!);

app.Run();

OpenAPI 文档可以在构建时或运行时从可访问的端点生成,并且可以根据需要使用文档和操作转换器定制生成的 OpenAPI 文档。 

使用 HybridCache 改进分布式缓存 

ASP.NET Core 对分布式缓存的支持正在通过新的 HybridCache API 进行升级。HybridCache 通过新功能骄加强了 ASP.NET Core 中现有的 IDistributedCache 支持,包括多层存储、有限的进程内 (L1) 缓存和单独的(通常较大)进程外 (L2) 缓存这种混合缓存存储方法兼具了两方面的优势,大多数提取操作都由 L1 高效处理,但由于 L2 的存在,冷启动和不常访问的数据仍然不会对底层后端造成影响。HybridCache 还包括踩踏保护(以防止并行提取相同工作)和可配置序列化,同时简化了常见场景的 API 使用 

以下是 HybridCache 实际运行的一个示例 

public class SomeService(HybridCache cache)
{
    public async Task<SomeInformation> GetSomeInformationAsync(string name, int id, CancellationToken token = default)
    {
        return await cache.GetOrCreateAsync(
            $"someinfo:{name}:{id}", // unique key for this combination
            async cancel => await SomeExpensiveOperationAsync(name, id, cancel),
            token: token
        );
    }
}

HybridCache 旨在替代大多数 IDistributedCache 场景,同时提供更多功能、更好的可用性和更高的性能。在我们的基准测试中,由于 HybridCache 具有多层缓存存储,它在高缓存命中率场景中比使用 IDistributedCache 快近 1000 倍。使用不可变类型时,缓存性能会进一步提高 

Image build hybridcache

 

使用 Blazor 的全栈 Web UI 

Blazor 使为 ASP.NET Core 应用构建 Web UI 变得简单而高效。已升级到 .NET 8 Blazor 开发人员一直在利用新功能,包括静态服务器渲染、流式渲染、加强的导航和表单处理等 

Image build blazor overview

 

来自开发人员的反馈非常棒,我们一直在不断改进 Blazor,提供新功能,您今天可以在最新的 .NET 9 预览版中试用,其中包括 

  • 组件构造函数注入:Blazor 现在除了支持使用 @inject 进行属性注入之外,还支持组件的构造函数注入。构造函数注入支持可选服务,并且非常适合空状态检查 
  • WebSocket 压缩:现在默认压缩用于交互式服务器渲染的 WebSocket 流量,从而显着减少消息负载大小 
  • 从全局交互应用中静态渲染页面:现在,您可以从为全局交互设置的 Blazor Web 应用中的交互式路由中排除页面,并强制它们从服务器静态渲染。当您的大多数应用都是交互式的,但某些页面必须在请求上下文中渲染时​​,这很有用 

请务必查看发行说明,以获取有关 .NET 9 ASP.NET Core 的新增功能以及未来 ASP.NET Core 路线图的更多详细信息 

使用 .NET 进行多平台开发 

.NET MAUI .NET 的多平台应用程序 UI,用于构建跨 iOS、Android、Mac Windows 平台精美的应用程序 

Image build dotnetmaui overview

 

自推出以来,我们看到了新用户爆炸式的增长和采用,现有的 Xamarin 开发人员也纷纷迁移以利用新功能和新性能每天使用的应用程序都是使用 .NET MAUI 构建的,包括 NBC Sports、Hawaiian Airlines、UPS、Microsoft Azure、DigiD、Seeing AI、E-ZPass Pennsylvania等等。 我们很高兴看到 .NET 社区继续支持构建漂亮的 .NET MAUI 库和控件(例如 .NET MAUI 社区工具包)以及控件供应商们例如 TelerikSyncfusionGrialDevExpress 等)的持续支持。 我们很荣幸得到您的支持,确保 .NET MAUI 成为构建多平台应用程序的世界级体验 

Image build dotnetmaui customers

 

.NET 8 中,我们致力于提高性能和质量、支持我们的生态系统、改善开发人员体验,并确保使用 .NET MAUI Blazor 构建一流的混合应用程序。 主要重点是将我们的开发流程转变为优先使用 NuGet 包。 这意味着我们可以快速部署新的服务版本,您可以在几秒钟内轻松升级。 今天,我们发布了 .NET 8 的第四个服务版本,提供了数百项您现在就可以利用的改进 

Image build dotnet maui hybrid blazor

 

去年,我们推出了使用 C# Dev Kit Windows、Mac Linux 上的 Visual Studio Code 中构建 .NET MAUI 应用的初始支持。本周,我们推出了 VS Code .NET MAUI 扩展的新版本,该扩展增加了对 XAML IntelliSense 的支持以及您一直期待的重大改进。看到开发人员利用 VS Code 在新平台上使用 .NET MAUI 构建应用,我们感到非常高兴,而且我们还将推出更多功能 

Image build dotnetmuai xaml

展望未来,我们将继续帮助 Xamarin 开发人员迁移到 .NET MAUI,并帮助 .NET MAUI 开发人员使用升级助手升级到较新版本的 .NET。 我们还将继续为 .NET 8 提供一致且可靠的服务版本同时继续在 .NET 9 中为多平台开发人员添加新功能您可以开始尝试我们的一些最新功能,例如 iOS 库多目标Android Asset Packs可在处理视频等大型资产时缩小应用程序大小),以及 iOS Mac Catalyst 应用程序的 Native AOT 实验性支持可将您的应用程序大小缩小高达 62%,同时使您的启动时间提高近 50%)! 在后续的预览中,您将看到一些使构建 .NET MAUI 混合应用程序更容易的功能,例如用于设置 Blazor Hybrid 和共享 UI Web 应用程序的新解决方案模板,以及用于启用 JavaScript 框架的新 HybridWebView 控件 

我们将继续优先考虑您的重要反馈,并鼓励您积极参与我们的 GitHub 存储库,关注我们的发布公告,并试用最新预览版和 VS Code 集成 

总之 

我们很高兴您能够尝试 .NET 中的所有这些新功能。 

  • 尝试使用我们的.NET AI 示例并在我们的文档中了解更多信息。 

如果您有任何技术问题,欢迎来Microsoft Q&A 提问。

Author

Amy Peng
Partner Tech Advisor

Amy Peng is a Partner Tech Advisor on the Dev Community Team focused on .NET. Her responsibility is providing technical support on the forum and promote .NET to all the community members.

1 comment

  • 承昊 周

    据我所知,razor页几乎没人用,而很多很多朋友在用aspx页。
    很奇怪,为什么netcore要放弃很多人用的aspx转而去做个没人用的东西呢?razor就是个html。
    please Support ASPX page on .netcore.
    how many people are using razor-page?it is a html.
    i know very more persons are using ASPX-page. i don’t known why netcore not support aspx?
    design for using,not for designing.
    设计是为了用的,不是为了设计而设计的,更不是为了显得自己高明而设计的。