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:
|
if (!ENVIRONMENT_IS_WORKER) { |
and
|
if (!ENVIRONMENT_IS_WORKER) { |
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:
|
export const ENVIRONMENT_IS_WORKER = ENVIRONMENT_IS_WEB_WORKER && !ENVIRONMENT_IS_SIDECAR; // we redefine what ENVIRONMENT_IS_WORKER, we replace it in emscripten internals, so that sidecar works |
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
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:
runtime/src/mono/browser/runtime/loader/assets.ts
Line 244 in 7dcd892
and
runtime/src/mono/browser/runtime/loader/assets.ts
Line 253 in 7dcd892
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:
runtime/src/mono/browser/runtime/loader/globals.ts
Line 30 in 28bbd27
The logic is a bit odd:
ENVIRONMENT_IS_WORKER is true if both of the following are true:
If globalThis.onmessage is undefined, globalThis.dotnetSidecar is set to true, ENVIRONMENT_IS_WORKER will be false, and loading works normally.
Reproduction Steps
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