How many threads does the uno-platform support for WASM (webassembly) projects?

435 Views Asked by At

I am trying to determine if the uno-platform will work for a specific project that I want to deploy as a WebAssembly app.

I've played around with Uno and have configured the newly available threading support using:

 <MonoWasmRuntimeConfiguration>threads-release</MonoWasmRuntimeConfiguration>

As I understand it, threading support is only available in Chrome and Edge at this time...but that is ok for my needs.

I've created a simple button that should spin up 10 worker threads like so:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                var t = new Thread(() => DoWork());
                t.Start();

            }

        }

        private void DoWork()
        {
            for (int n = 0; n < 10000; n++)
            {
                Console.WriteLine($"Task {Thread.CurrentThread.ManagedThreadId} running {n}");
            }
        }

This code is the only thing added to the default "hello world" WASM project from the uno-platform templates.

When looking at the output, I can see that 2 threads are working as expected and interweaving results. (prior to the <MonoWasmRuntimeConfiguration>threads-release</MonoWasmRuntimeConfiguration> the output would be synchronous for a single "thread" and then synchronous for the next "thread")

Task 3 running 9987

Task 2 running 9843

Task 3 running 9988

At the completion of both threads, the follow warning is logged in the browser console.

PThread 70424616 is attempting to join to itself!
__emscripten_do_pthread_join @ dotnet.js:1
_pthread_join @ dotnet.js:1
mono_native_thread_join @ 00806cba:0x70078
threads_native_thread_join_lock @ 00806cba:0xbfd98
mono_threads_join_threads @ 00806cba:0x6aefe
mono_runtime_do_background_work @ 00806cba:0xdb520
mono_background_exec @ 00806cba:0xf89c5
Module._mono_background_exec @ dotnet.js:1
pump_message @ dotnet.js:1
setTimeout (async)
_schedule_background_exec @ dotnet.js:1
mono_threads_schedule_background_job @ 00806cba:0x1612c
mono_threads_add_joinable_runtime_thread @ 00806cba:0xd8aa4
sgen_client_thread_detach_with_lock @ 00806cba:0xc67bd
thread_detach_with_lock @ 00806cba:0xc0142
unregister_thread @ 00806cba:0x5e469
mono_thread_info_detach @ 00806cba:0xd98c6
mono_thread_info_exit @ 00806cba:0x49724
start_wrapper @ 00806cba:0xc1206
dynCall_ii @ 00806cba:0x11d3d7
Module.dynCall_ii @ dotnet.js:1
onmessage @ dotnet.worker.js:1

Two questions arise which I can't find documentation about.

  1. Why only 2 threads? (on both Chrome and Edge) Is this a browser limitation? A setting in Uno-platform?
  2. Why do the remaining 8 threads not get started? They are essentially lost and none of the work gets performed. Is this a bug in the uno-platform? Mono? emscripten possibly?

I know threading is still experimental, but I am curious if there is a known limitation that I am hitting?

1

There are 1 best solutions below

1
On

The number two may come from the default provided by emscripten, with the default number of workers provided before the main of the application. You can change the default number of threads with this:

<ItemGroup>
    <WasmShellExtraEmccFlags Include="-s PTHREAD_POOL_SIZE=10"/>
</ItemGroup>

The support for threads is likely to improve a lot during the .NET 6 timeframe, so this may change signficantly.