Skip to content

Setting WasmEnableThreads to true on .NET 9.0 WebAssembly dev server should tell you it's not going to work #116251

Open
@idg10

Description

@idg10

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

  1. In Visual Studio 2022 create a new Blazor WebAssembly project targetting .NET 9.0. (This adds references to Microsoft.AspNetCore.Components.WebAssembly and Microsoft.AspNetCore.Components.WebAssembly.DevServer v9.0.5)
  2. Run the application. It works.
  3. In the csproj, add <WasmEnableThreads>true</WasmEnableThreads> in a PropertyGroup
  4. Delete the bin and obj folders as suggested for WasmEnableThreads incrementalism is broken #98502
  5. Rebuild
  6. 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions