Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Blazor / .NET WASM: Direct interop method calls to .NET hang randomly #117698

Unanswered
Sebazzz asked this question in Q&A
Discussion options

We're in the process of rebuilding an internal jQuery-based Electron application in Blazor + C#/WASM using a hybrid model: Replacing UI or backend code as we go. We run into the issue of .NET method calls being unreliable, and I have not seen any issue mentioning it so I wonder if I'm doing something wrong. I have the issue with both .NET 9.0, and the .NET 10 preview and both with the ST and MT runtime (WasmEnableThreads).

Take this simple method to call. The contents actually turn out not to matter because when the method call hangs the managed code is never executed.

public static partial class Repository { 
 [JSExport]
 public static Task InitializeEfrDataStreamAsync() {
 return Task.Delay(100); // Seems like: https://github.com/dotnet/runtime/issues/106788
 }
}
<script src="_framework/blazor.webassembly.js"></script>

Small thing to make interop easier, note that iframes is used but dotnet itself also only initializes once in window.top itself.

export async function afterWebAssemblyStarted() {
 const solutionName = "MyProject";
 const projectName = "Web";
 const assemblyName = `${solutionName}.${projectName}`;
 // Bail out if already available globally
 if (typeof window.top.DotNetInterop !== "undefined") return;
 // Make the exports available globally
 const { getAssemblyExports } = await globalThis.getDotnetRuntime(0);
 const exports = await getAssemblyExports(`${assemblyName}.dll`);
 window.top.DotNetInterop = exports[solutionName][projectName];
 console.log("WebAssembly initialized", window.top.DotNetInterop);
}

And the call itself (but as mentioned, it doesn't seem to matter what the signature or contents is):

await window.top.DotNetInterop.DataModel.Repository.InitializeEfrDataStreamAsync();

Symptoms and observations:

  • The issue shows itself as an unresolved promise (=pending forever)
  • There is no time-out or anything happening, you can leave it 15 minutes and it still hangs
  • The issue is reproducible from both normal Javascript code and from console calls in the dev tools
  • The issue seems to happen about 80% of the time, with 20% of the time the method call going through fine. The issue only happens on the first call: if the first call succeeds, not any other method call will hang (= unresolved promise). If the first call hangs, not any subsequent call will come through.
  • It appears to happen only with [JSImport]/[JSExport] based calls. If we instead proxy through Blazor using [JSInvokable] the issue does not occur. Must be noted though that JSInvokable appears to have ~20% overhead per call.
  • It doesn't matter if WasmEnableThreads is enabled or not (I took care to do a clean build given issue WasmEnableThreads incrementalism is broken #98502 )
  • No hanging network calls are observed

So what does work is invoking through myBlazorComponent.invokeMethodAsync('InitializeEfrDataStreamAsync') and that works consistently.

Additional context:

  • We're serving the entire application from a local running webserver, which proxies the necessary prefixes like _framework and _content to the .NET development server. This is necessary in order to inject the proper COERS/CORP headers to support SharedArrayBuffer. Unfortunately it seems Electrons interception callbacks aren't properly called from web workers so this is a workaround.
  • The application itself uses iframes, but .NET seems to be aware and properly attaches itself already to window.top

Unrelated issues in the same bucket: #106788 #114140 #114918 #76963

CC'ing @pavelsavara and @SteveSandersonMS who I had a conversation with in another issue.

Does anyone have any pointers or ideas?

You must be logged in to vote

Replies: 3 comments 4 replies

Comment options

Task.Delay is implemented via JS setTimeout. Browsers sometimes throttle pages.

As you can see, there are open issue with MT and with web-workers. Is this scenario also related to a webworker ?

We don't have automated tests for Electron. I don't know how different the V8 integration of promises would be there.

Can you reproduce in a chrome browser and in firefox ?
To narrow the scope, is it dotnet bug, electron bug, chrome bug, webworker in chrome bug ?

You must be logged in to vote
1 reply
Comment options

Task.Delay is implemented via JS setTimeout. Browsers sometimes throttle pages.

Right, but as mentioned, the call never reaches that method. The Task.Delay was actually implemented before finding out it was never reached.

Is this scenario also related to a webworker ?

No, calling this from the main UI JS thread.

Can you reproduce in a chrome browser and in firefox ?

Not really possible, given the Electron environment.

Comment options

Also are you sure that afterWebAssemblyStarted runs after the dotnet is fully initialized ? (race condition)

You must be logged in to vote
1 reply
Comment options

Also are you sure that afterWebAssemblyStarted runs after the dotnet is fully initialized ? (race condition)

Yes, it is called by Blazor actually. See: https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/startup?view=aspnetcore-9.0#javascript-initializers

Comment options

Hi @Sebazzz , was this solved? Something similar happened with my code today and I'm not sure if I am implementing it wrong. Yesterday it was working but today it no longer is. It just hangs like that once the function is called.

You must be logged in to vote
2 replies
Comment options

"Glad" you ran into the same issues.
For us, it was pretty much resolved by upgrading to the .NET 10 preview and later to the RC and RTM version when it became available. By now the Electron app is running in production on at least 1000 clients and I haven't heard anything of issues causing apparent hanging calls.

Comment options

Before I forget, we've removed most frames from the application because we ran into other issues with Blazor - including debugging issues. But I think this is unrelated to the issues with the hanging method calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /