Description
Description
Adding <WasmEnableThreads>true</WasmEnableThreads>
to a newly-created standalone Blazor WebAssembly application (.NET 9.0) stops it from loading.
After some investigation, I've come to the conclusion that this is because multithreading in Blazor WebAssembly is not in fact supported in .NET 9.0. But it wasn't at all obvious. Setting this property causes some changes in behaviour: the devserver adds extra CORS headers, and the page loads a different version of the CLR, the version built with multithreading support enabled. So the signs seem to indicate that it's meant to work, and there's no warning or error telling you that it won't.
If this is meant to work, then the fix already in place for .NET 10.0 preview should be backported to .NET 9.0. But if this is expected not to work, it would be useful to have some sort of message telling you that WasmEnableThreads
is not supported in this context.
Reproduction Steps
- In Visual Studio 2022 create a new Blazor WebAssembly project targetting .NET 9.0. (This adds references to
Microsoft.AspNetCore.Components.WebAssembly
andMicrosoft.AspNetCore.Components.WebAssembly.DevServer
v9.0.5) - Run the application. It works.
- In the
csproj
, add<WasmEnableThreads>true</WasmEnableThreads>
in aPropertyGroup
- Delete the
bin
andobj
folders as suggested for WasmEnableThreads incrementalism is broken #98502 - Rebuild
- Run the application. The progress circle appears and goes to 100%, but then nothing happens. No errors either in the browser or Visual Studio.
I see the same behaviour on Edge and Chrome, both of which are fully up to date as of 2025/06/03.
Expected behavior
Either the application should run as normal (just as it does without the <WasmEnableThreads>
setting), or the tools should provide some sort of message to tell us that this will not work.
Actual behavior
The progress circle appears and goes to 100%, but then nothing happens. No errors either in the browser's dev tools Console or in Visual Studio. Configuring the browser debugger to pause on caught and uncaught exceptions does not help—the browser never reports any exceptions being thrown.
Although there are no errors, the dev tools "Issues" section reports problems when it fetches https://localhost:7209/_framework/dotnet.native.worker.1t59g4t9vs.mjs
. Specifically, it reports CORS problems with this. See "Other Information" section for more detail.
Regression?
No response
Known Workarounds
Use .NET 10.0 preview.
Configuration
dotnet --info
reports:
.NET SDK:
Version: 9.0.300
Commit: 15606fe0a8
Workload version: 9.0.300-manifests.87b8cca8
MSBuild version: 17.14.5+edd3bbf37
Runtime Environment:
OS Name: Windows
OS Version: 10.0.26100
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\9.0.300\
and
Microsoft.NETCore.App 9.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Visual Studio 2022 v17.14.3
Wasm-tools:
[wasm-tools]
Installation Source: SDK 9.0.300
Manifest Version: 9.0.5/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.workload.mono.toolchain.current\9.0.5\WorkloadManifest.json
Install Type: Msi
Edge reports "Version 137.0.3296.58 (Official build) (64-bit)".
Chrome reports "Version 137.0.7151.69 (Official Build) (64-bit)".
Other information
The failure to load appears to be because the main HTML page served up by the dev server sets a Cross-Origin-Embedder-Policy: require-corp
header, but when the browser attempts to download the dotnet.native.worker
resource (in my case, https://localhost:7209/_framework/dotnet.native.worker.1t59g4t9vs.mjs
, but I presume that jumble of chars on the end is context-specific), the dev server does not set a Cross-Origin-Embedder-Policy
header.
I believe the reason Cross-Origin-Embedder-Policy
gets set is that this is necessary for multithreading to work in practice. (I believe it is a prerequisite for sharing of memory, without which multithreading is not very useful.) But because it's not getting set on all relevant files, it causes the app to fail to load.
It looks like a fix for this already exists for .NET 10 preview: https://github.com/dotnet/aspnetcore/blob/aa0ae536e89b8b8e2c2ecb1cb336451cf45387e5/src/Components/WebAssembly/DevServer/src/Server/Startup.cs#L46
That fix has not made it to the .NET 9.0 branch as of 2025/06/03: https://github.com/dotnet/aspnetcore/blob/release/9.0/src/Components/WebAssembly/DevServer/src/Server/Startup.cs#L46
Note that the 9.0 branch does not have the test for the .mjs
extension.
But since this is prevents the WasmEnableThreads
setting from working on .NET 9.0 today, it would be great for this same fix to be brought onto the .NET 9.0 branch. However, I can believe that use of multithreading in the browser is entirely unsupported in .NET 9.0, in which case it would be better if the tooling just told us that, instead of making a bunch of changes in behaviour that strongly suggest that it's supposed to work.