Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS Interop only works on main thread when using multiple threads #799

Open
Rippletank opened this issue Nov 7, 2023 · 4 comments
Open

Comments

@Rippletank
Copy link

UnoWASMnet80TheadsAndJSInterop.zip

Background

Working on porting an existing app to Uno platform. Have implemented javascript replacements for many features not currently supported by WASM, such as cryptography, database, speech etc.

Issue

Using the JSImportAttribute and JSHost.ImportAsync works fine on the main thread but throws an exception "Please use dedicated worker for working with Javacsript interop" when run on a thread pool thread.

The exception seems to be thrown because there is no CurrentJSSynchronizationContext for the given thread in JSSynchronizationContext .

I can't find where this is actually set for the main thread. There is a WebWorker class which does install the required synchronisation contexts. However, I can't find any way to access this class anywhere. I did also try a UseWasmExperimental setting that was mentioned somewhere for .net7.0 but this didn't appear to do anything.

Reproduction

Attached project is minimal reproduction of the issue (reporting to console) for a simple synchronous and async call.

Workaround

Redirect all interop calls to main thread. However, this means that the main thread is blocked and animations stutter and controls are unresponsive as would be expected. I have set up a JS worker to handle the database calls once on the JS side.

Solution?

I am not familiar with how the Dotnet and Uno Platform git repos correspond with what is packaged, but is it possible to make the WebWorker class accessible? Failing that, is there any other way of getting more than one thread setup to run JS calls?

@jeromelaban
Copy link
Member

I'm not sure about all the specifics that you are mentioning, but overall, Uno does not provide any API over what .NET provides. If you're building with a net8.0 TFM and .NET 8 RC 2 , WebWorker should be available like any other API and should be useable.

@Rippletank
Copy link
Author

Ok, I understand. I'm still trying to familiarise myself with where different parts are coming from.

In your experience, would you suggest the dotnet/runtime Github be the most effective place to ask about this?

For the record, the Microsoft.NETCore.App\8.0.0-rc.2.23479.6\System.Runtime.InteropServices.JavaScript.dll does not appear to have the WebWorker class according to dotPeek.

As an addition to the workaround above, I would add careful profiling because some unexpected parts of WASM/Dotnet seem to be really slow. Avoid any cryptography, even the few algorithms that are implemented are hundreds of times slower than sending it over to JS and doing it all there using SubtleCrypto. And serialization is also very slow. Check to make sure you are only doing it once and for large numbers of simple types it can be much faster to avoid it at all and use StringBuilder and Uno.Foundation.WebAssemblyRuntime.EscapeJS.

@SerratedSharp
Copy link

Yep, most of the newer interop features that were introduced in .NET 7 including everything under System.Runtime.InteropServices.JavaScript are maintained under dotnet/runtime. It can be a bit confusing sometimes figuring out where the line is drawn. Before .NET 7 had these features, Uno libraries provided these interop capabilities to fill that need.

@jeromelaban
Copy link
Member

In your experience, would you suggest the dotnet/runtime Github be the most effective place to ask about this?

dotnet/runtime would be the best place to ask questions about it, definitely. Uno only bundles the runtime as-is (with some minor configuration changes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants