引言:为什么WebAssembly正在改变C#开发者的游戏规则
长期以来,Web开发一直是JavaScript的天下。然而,随着WebAssembly (Wasm)的出现,情况发生了根本性的变化。现在,C#开发者可以将其代码编译成二进制格式,在浏览器中以接近原生的速度执行。这开辟了巨大的可能性:从移植重型算法到使用Blazor创建完整的SPA应用程序。
在本文中,我们将探讨WebAssembly如何与C#和.NET协同工作,介绍关键工具(Blazor、Wasmtime、Mono),并编写实践示例。到文章结束时,您将能够独立地在浏览器或服务器上使用Wasm运行C#代码。
WebAssembly基础及其与C#的集成
简单来说,什么是WebAssembly
WebAssembly是一种低级字节码,在浏览器的虚拟机中执行。它不会取代JavaScript,而是与之协同工作。主要优势包括:
- 性能:二进制代码的执行速度比JS快30-50%。
- 安全性:隔离的执行环境。
- 可移植性:同一个.wasm文件可以在Chrome、Firefox、Safari和Edge中运行。
对于C#生态系统,WebAssembly通过几个项目实现:Blazor WebAssembly(UI框架)、Mono Wasm Runtime(执行IL代码)和Wasmtime(用于服务器端场景)。
C#如何编译为WebAssembly
过程如下:
- 您用C#编写代码。
- Roslyn编译器将其转换为IL(中间语言)。
- Mono Runtime(或NativeAOT)将IL转换为WebAssembly。
- 浏览器加载.wasm文件并执行它。
重要提示:有两种方法——通过Mono解释(较慢但更简单)和AOT编译(更快但需要配置)。
实践:在WebAssembly中运行C#的三种方法
1. Blazor WebAssembly — 用于Web界面
Blazor允许您用C#而不是JavaScript编写客户端部分。所有UI代码和业务逻辑都编译为Wasm。
简单组件示例:
@page "/counter"<h3>计数器:@currentCount</h3><button @onclick="IncrementCount">+1</button>
@code { private int currentCount = 0;
private void IncrementCount() { currentCount++; }}这段代码在浏览器中执行。Blazor会自动加载Mono Wasm Runtime和您的.wasm文件。要开始,请创建一个项目:
dotnet new blazorwasm -o MyBlazorAppcd MyBlazorAppdotnet run结果:一个完整的SPA应用程序,没有一行JavaScript代码。
2. 使用NativeAOT直接编译为.wasm
如果您需要执行特定函数(非UI),请使用NativeAOT——它直接将C#编译为原生WebAssembly,无需Mono Runtime。
步骤:
- 安装.NET 8+ SDK和工作负载:
dotnet workload install wasm-tools - 创建控制台应用程序:
dotnet new console -n WasmDemocd WasmDemo- 修改
.csproj,添加Wasm支持:
<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <RuntimeIdentifier>browser-wasm</RuntimeIdentifier> <UseNativeAot>true</UseNativeAot></PropertyGroup>- 编写代码:
using System;
public class Program{ public static void Main() {