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

Run .NET in a worker thread #5475

SteveSandersonMS opened this Issue Feb 19, 2018 · 9 comments


None yet
8 participants
Copy link

SteveSandersonMS commented Feb 19, 2018

It will be a while before we get to this, but various parts of the architecture are already designed with this in mind.

We should support running Blazor in two modes, auto-selecting which one is best for the current user's browser:

  • On the browser's main JS thread, which is necessary for older browsers that don't support WebWorker. The .NET/JS interop can continue using shared memory if we find it's necessary to have good perf on those older browsers (and thread safety is not difficult because it's all synchronous).
  • In a web worker (background thread) on more up-to-date browsers. The .NET/JS interop will need to work by serializing any data that is being transferred rather than passing pointers [1].

This will be advantageous because then, even if your .NET code does something that locks up the CPU (such as a GC cycle), the UI will remain perfectly smooth (e.g., during animations or scrolling, or while the user is typing quickly into a textbox).

The existing UI update mechanism is designed around transferring batches of minimal diffs from .NET to JS, so it shouldn't be hugely difficult to have it express those diffs as serialized data rather than pointers into the WASM memory space. We'll have to be careful around things like event handling to ensure that the asynchrony can't result in inconsistency of behaviour versus the synchronous single-threaded model. For example, we will need to force all event delivery to be async as far as the JS side is concerned, even in the non-worker-thread case.

[1] Strictly speaking, we could also do it with shared memory on even newer browsers that support SharedArrayBuffer. But if we can get satisfactory perf without this, it would be better to serialize because it would mean fewer combinations of browser scenarios, and saves us having to deal with potentially complex thread-safety concerns on the .NET side.


This comment has been minimized.

Copy link

vibeeshan025 commented Feb 25, 2018

The .NET/JS interop will need to work by serializing any data that is being transferred rather than passing pointers [1]

Since new web browsers support SharedArrayBuffer it's better to support that.

If multiple browser combination is a problem then we can have only two combinations as below.

  1. On the browser's main JS thread mode
  2. Full thread support with shared memory. Any browser that doesn't support shared array buffer will work on mode 1.

Maybe for C# dynamic objects we can use serialization since we can't predict the size of the object in the compile time.

It's like we are designing it for the future with full .net like threading support ( 1 or 0 no gray), we should not compromise on performance for compatibility.

We have enough js frameworks out there, the real game changer should provide a multitude of performance improvement over what existing frameworks provide.

I see this as a framework going to crush any js framework out there. Angular, react Vue etc.


This comment has been minimized.

Copy link

wanton7 commented Feb 25, 2018

@vibeeshan025 so you want to limit support for web worker just to use SharedArrayBuffer? That doesn't make no sense what so ever.
First support what works in most browsers so that you get smoothest possible Blazor experience in many browsers as possible to compete with existing SPA frameworks/libraries. Then later think about adding more choices for serialization.

SharedArrayBuffer was also disabled in browsers 5 January, 2018 due to Spectre vulnerability and it's probably still be disabled.


This comment has been minimized.

Copy link

SteveSandersonMS commented Feb 25, 2018

Thanks for the thoughts from both of you!

@vibeeshan025 I think your suggestion is interesting and has merit. We'll have to see what the actual perf effects of different choices are, and what level of browser support exists for SharedArrayBuffer, when we get to implementing this.


This comment has been minimized.

Copy link

joeizy commented Mar 8, 2018

NativeScript opted to follow a single threaded by default model for JS and native code on mobile devices. This gave them the ability to do some interesting things with native APIs that aren’t achieved in other run times such as ReactNative. It also simplified the programming model because single UI thread is what you expect when working with UI unless you explicitly dispatch another thread.

I’m not familiar enough with Blazor or WebAssembly to comment pros / cons but I thought it would be interesting to bring two existing examples that were implemented differently and have their associated consequences.

One that stands out which may be relevant is custom animations. Not being on the UI thread creates a lot of back and forth if you’re trying to do real-time or frequent updates to UI elements such as in custom animation scenarios. Painful in early versions of ReactNative and my understanding is direct byproduct running on a background thread.


This comment has been minimized.

Copy link

Thaina commented Apr 8, 2018

I am more align with UI thread for blazor, and using webworker thread only with intentionally multithread API (such as Threading and Concurrent). So we would have fully intended code to control UI with blazor


This comment has been minimized.

Copy link

galvesribeiro commented May 24, 2018

Just a reminder... SharedArrayBuffer is disabled on all major browsers since specter disclosure...


This comment has been minimized.

Copy link

cician commented Jun 2, 2018

I'd love the ability to run .net code in a worker thread. Not just for concurrency, but in order to actually isolate code in a separate wasm module since I want to dynamically load and unload assemblies, which doesn't otherwise seem possible right now as far as I can tell (no AppDomains or AssemblyLoadContext). Complete isolation is actually desirable for my use case (compiling and running potentially untrusted code).
That being said I'm eagerly waiting for actual multi-threading with shared memory.


This comment has been minimized.

Copy link

vibeeshan025 commented Oct 31, 2018

Google chrome started implementing threads in c++ style

@aspnet-hello aspnet-hello transferred this issue from aspnet/Blazor Dec 17, 2018

@aspnet-hello aspnet-hello added this to the Backlog milestone Dec 17, 2018

@cician cician referenced this issue Jan 3, 2019


Next steps #16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment