Description
Description
When dotnet.js is started in a web worker with an onmessage handler, the promises for asset instantiation are never resolved and therefore initialization hangs.
There appears to be a check in browser/runtime/loader/assets.ts which checks for ENVIRONMENT_IS_WORKER and deliberately avoids resolving the promises:
and
If ENVIRONMENT_IS_WORKER is manually set to false in the debugger, loading will complete normally and dotnet.js functions correctly in a web worker.
ENVIRONMENT_IS_WORKER is set here:
The logic is a bit odd:
ENVIRONMENT_IS_WORKER is true if both of the following are true:
- importScripts is a function
- globalThis.onmessage is truthy
If globalThis.onmessage is undefined, globalThis.dotnetSidecar is set to true, ENVIRONMENT_IS_WORKER will be false, and loading works normally.
Reproduction Steps
<script>
const dotnetUrl = 'dotnet.js';
const wasmConfig = {} // blazor.boot.json or equivalent here
const workerSrc = `self.onmessage = async (initialMsg) => {
const { dotnet } = await import('${dotnetUrl}');
const { setModuleImports, getAssemblyExports } = await dotnet.withConfig(${JSON.stringify(wasmConfig)}).create();
const assembly = await getAssemblyExports('WasmWorker');
};`;
const workerBlob = new Blob([workerSrc], {type: 'application/javascript'});
const workerUrl = URL.createObjectURL(workerBlob);
const worker = new Worker(workerUrl, { type: 'module'});
worker.postMessage('init');
</script>
Expected behavior
dotnet.js initializes successfully in the web worker.
Actual behavior
The dotnet.create() promise is never resolved and initialization hangs.
Regression?
This worked correctly in .NET 8.
This commit introduced the logic which breaks loading in a web worker with an onmessage handler:
8698d3d
Known Workarounds
Delete any globalThis.onmessage handler before calling dotnet.create()
Configuration
.NET SDK 9.0.203
Behavior can be reproduced in Chrome, Safari, Firefox, and presumably any other browser that Blazor supports.
Other information
No response