dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.45k stars 10.03k forks source link

Real multithreading in Blazor WebAssembly #17730

Open BlenderMender opened 4 years ago

BlenderMender commented 4 years ago

Is your feature request related to a problem? Please describe.

I have load of CPU intensive requests connected to vial for the application data from sensors, and I would like to have a real multithreading for multiple sources which streams large amount of data nonstop.

Describe the solution you'd like

Multithreading which is available already in WEBASM to be exposed to Blazor Client side.

mattgenious commented 2 years ago

I agree with @chingham but also have a vested interest in how multithreading might impact startup time of both the mono runtime and blazor and how this might prevent UI locking when loading a prerendered blazor wasm application.

Any thoughts on this?

Cpt-Falcon commented 2 years ago

I agree with @chingham but also have a vested interest in how multithreading might impact startup time of both the mono runtime and blazor and how this might prevent UI locking when loading a prerendered blazor wasm application.

Any thoughts on this?

I don't imagine it would affect loading times for blazor at all. I mean all of the task library logic is already loaded as part of standard blazor wasm. All that would happen is the task pool gets access to multiple threads if needed. Task pool threads get started up as needed in the background

mattgenious commented 2 years ago

I agree with @chingham but also have a vested interest in how multithreading might impact startup time of both the mono runtime and blazor and how this might prevent UI locking when loading a prerendered blazor wasm application. Any thoughts on this?

I don't imagine it would affect loading times for blazor at all. I mean all of the task library logic is already loaded as part of standard blazor wasm. All that would happen is the task pool gets access to multiple threads if needed. Task pool threads get started up as needed in the background

Ah fair but I was thinking more in regards to starting the mono runtime without locking input fields, currently we have users waiting upwards of 20 seconds on old ios/android devices for the mono runtime to load before being able to use an input field.

I appreciate that the runtime needs time to start, but it seems to me that multithreading in the runtime would allow this to be handled without blocking the UI thread.

The poor startup time of blazor webassembly is my only real gripe, I would even be able to allow being locked to a single thread if the startup time was not so poor.

But maybe I am misunderstanding the architecture here?

ivanjx commented 2 years ago

are you sure that it is not because of the network speed @mattgenious?

mattgenious commented 2 years ago

are you sure that it is not because of the network speed @mattgenious?

100% I can see the "mono runtime ready" event firing after 20 seconds and then the UI locking stops 😊

mattgenious commented 2 years ago

are you sure that it is not because of the network speed @mattgenious?

100% I can see the "mono runtime ready" event firing after 20 seconds and then the UI locking stops 😊

Also given that the best case startup time on firefox and chrome is around 1.67 seconds on a 24-core cpu with 32g ram it doesn't surprise me that much that some older mobile devices like iPhone 6s and Oneplus Nord have massive load times. I just wish it weren't so 😊

YordanYanakiev commented 2 years ago

I have feeling that this unreasonable delaying of Mono support of multithreading is a favor to Apple devices which does not support real multithreading. I am really curious when Microsoft shall stop doing favor to other companies and put his own things first. ( Point the favor to dump Flash, which was one of the things lacking the other platforms, and users were really into. Billions dollars per year were made just from the Flash games in Facebook alone, and Microsoft easily gave it on it, practically ditching 95% of his users gaming needs - a business worth currently at least 600 billion dollars, which is currently divided between Google and Apple instead of Microsoft just pay a group of programmers to help Adobe fix the "bad exploits" and keep going with it. Just the same story repeat now with Mono as I am seeing the things from my probably wrong point of view ;)

mattgenious commented 2 years ago

I have feeling that this unreasonable delaying of Mono support of multithreading is a favor to Apple devices which does not support real multithreading. I am really curious when Microsoft shall stop doing favor to other companies and put his own things first. ( Point the favor to dump Flash, which was one of the things lacking the other platforms, and users were really into.

Billions dollars per year were made just from the Flash games in Facebook alone, and Microsoft easily gave it on it, practically ditching 95% of his users gaming needs - a business worth currently at least 600 billion dollars, which is currently divided between Google and Apple instead of Microsoft just pay a group of programmers to help Adobe fix the "bad exploits" and keep going with it.

Just the same story repeat now with Mono as I am seeing the things from my probably wrong point of view ;)

While I appreciate the sentiment I feel that this might be a bit off topic and according to https://webassembly.org/roadmap/ the ios safari browser actually seems to support real multithreading if I'm not misunderstanding something.

I would also like to point out that I think that waiting for webassembly to finish its spec for multithreading seems reasonable, were it not for the fact that most browsers have already implemented support based on the draft specification.

To ensure the feasability of Blazor Webassembly as a potentially broadly used front end framework for SPA's, I feel we have to make it a priority that the startup time for the mono runtime and subsequent Blazor framework be optimizid as much as possible 😊

boukenka commented 2 years ago

@mattgenious Would it help to improve the startup speed with Lazy Loading? Sorry if this is off topic.

sps014 commented 2 years ago

@danroth27 @mkArtakMSFT running multi threading require SharedArrayBuffer but SharedArrayBuffer is only available to pages that are cross-origin isolated. in actual deployment of wasm app do we need to add Cross-Origin-Embedder-Policy: require-corp and Cross-Origin-Opener-Policy: same-origin headers manually or it will handled automatically?

YordanYanakiev commented 2 years ago

I would like to not that all of the limitations before the multithreading is artificial created to support the current ideology of the single threading javascript, and maybe it is time to look beyond javascript, since this was the original idea of Blazor. Isn't it ?

mattgenious commented 2 years ago

@mattgenious Would it help to improve the startup speed with Lazy Loading? Sorry if this is off topic.

It wouldn't make a difference as the mono runtime has to start before even a smaller assembly is loaded and will still be doing so on a single thread effectively blocking the UI thread. But I appreciate the input :-)

Cpt-Falcon commented 2 years ago

@mattgenious Would it help to improve the startup speed with Lazy Loading? Sorry if this is off topic.

It wouldn't make a difference as the mono runtime has to start before even a smaller assembly is loaded and will still be doing so on a single thread effectively blocking the UI thread. But I appreciate the input :-)

So is the problem a CPU cycles issue where once the mono runtime has been initially transferred to the client, there is a lot of processing going on that needs to occur before things could start? Or is this an initial transfer issue such that if you were to use http3 it could accelerate the initial load since all the files could be transferred in parallel on start over udp like protocol?

If its a processing problem why can't everything be preprocessed on the server side and then sent to the client which can run as is?

chingham commented 2 years ago

Is it just me or discussion has shifted from multithreading to loading times ?

mattgenious commented 2 years ago

@mattgenious Would it help to improve the startup speed with Lazy Loading? Sorry if this is off topic.

It wouldn't make a difference as the mono runtime has to start before even a smaller assembly is loaded and will still be doing so on a single thread effectively blocking the UI thread. But I appreciate the input :-)

So is the problem a CPU cycles issue where once the mono runtime has been initially transferred to the client, there is a lot of processing going on that needs to occur before things could start? Or is this an initial transfer issue such that if you were to use http3 it could accelerate the initial load since all the files could be transferred in parallel on start over udp like protocol?

If its a processing problem why can't everything be preprocessed on the server side and then sent to the client which can run as is?

We are prerendering the application on the server side, serving it, then starting up the wasm app. The behavior is as follows:

I am certain that it is not the transfer of files but the processing of mono and blazor taking up almost all of that wait time as I have tested many times with everything cached, and when it is not, the UI is not locked while the webassembly app is being downloaded, only when startup of the runtime is initiated.

danroth27 commented 2 years ago

We are prerendering the application on the server side, serving it, then starting up the wasm app. The behavior is as follows:

  • Html is rendered instantly and starts loading the webassembly (which is cached in this case)
  • For less than a second the UI is responsive and then locks up as startup of the mono runtime and app is handled
  • depending on the device it takes between 1.6 seconds and 29 seconds (tested today on an iPhone 5s with ios 12.2) before UI is responsive again.

I am certain that it is not the transfer of files but the processing of mono and blazor taking up almost all of that wait time as I have tested many times with everything cached, and when it is not, the UI is not locked while the webassembly app is being downloaded, only when startup of the runtime is initiated.

@mattgenious If you haven't already, I think you should open a separate issue for this so that we can investigate your specific startup performance issue.

mattgenious commented 2 years ago

We are prerendering the application on the server side, serving it, then starting up the wasm app. The behavior is as follows:

  • Html is rendered instantly and starts loading the webassembly (which is cached in this case)

  • For less than a second the UI is responsive and then locks up as startup of the mono runtime and app is handled

  • depending on the device it takes between 1.6 seconds and 29 seconds (tested today on an iPhone 5s with ios 12.2) before UI is responsive again.

I am certain that it is not the transfer of files but the processing of mono and blazor taking up almost all of that wait time as I have tested many times with everything cached, and when it is not, the UI is not locked while the webassembly app is being downloaded, only when startup of the runtime is initiated.

@mattgenious If you haven't already, I think you should open a separate issue for this so that we can investigate your specific startup performance issue.

Will do, I apologize for causing this much noise, that wasn't my intention.

danroth27 commented 2 years ago

Will do, I apologize for causing this much noise, that wasn't my intention.

No problem at all! Your startup performance problems sound significant, so I want to make sure they don't get lost in this issue.

danroth27 commented 2 years ago

We announced .NET 7 Preview 1 today, along with our planned roadmap for ASP.NET Core and Blazor. Support for multithreading in Blazor WebAssembly is planned for .NET 7. Plans can still change, so we'll see how it goes.

LoupaLoupa commented 2 years ago

Will .Net 7 be LTS or will there be a .Net 6.5 with Multithreading support?

Le me rejoice to this news! Best thing since slice bread ;)

Enderlook commented 2 years ago

Will .Net 7 be LTS or will there be a .Net 6.5 with Multithreading support?

Le me rejoice to this news! Best thing since slice bread ;)

The milestone of this issue says .NET 7. Also, I don't think they will make a .NET 6.5 since they release a new .NET version per year since the invention of .NET 5 (even more, they already released .NET 7 Preview 1), creating a minor version (.NET 6.5) wouldn't fit much the current scheme.

Xyncgas commented 2 years ago

where's the implementation, do we have it on github, any updates about this at all?

danroth27 commented 2 years ago

Will .Net 7 be LTS or will there be a .Net 6.5 with Multithreading support?

Le me rejoice to this news! Best thing since slice bread ;)

@LoupaLoupa .NET 7 will be a Current release. The next planned LTS release will be .NET 8 in Nov 2023. You can learn more about the .NET support policy here: https://dotnet.microsoft.com/platform/support/policy

danroth27 commented 2 years ago

where's the implementation, do we have it on github, any updates about this at all?

@Xyncgas The main implementation work for this feature is in the .NET WebAssembly runtime, which is handled in the https://github.com/dotnet/runtime repo.

Cpt-Falcon commented 2 years ago

where's the implementation, do we have it on github, any updates about this at all?

@Xyncgas The main implementation work for this feature is in the .NET WebAssembly runtime, which is handled in the https://github.com/dotnet/runtime repo.

This is awesome thanks, any ideas which preview release it will be planned for?

danroth27 commented 2 years ago

This is awesome thanks, any ideas which preview release it will be planned for?

Not yet. It's a pretty significant effort on the runtime side, and there are some investigations that need to be completed before we can get to a fully committed execution plan.

Cpt-Falcon commented 2 years ago

This is awesome thanks, any ideas which preview release it will be planned for?

Not yet. It's a pretty significant effort on the runtime side, and there are some investigations that need to be completed before we can get to a fully committed execution plan.

Makes sense, am I correct in assuming it will be purely based on the task pool, so no System.Thread()? The task pool will simply be given access to more threads?

sps014 commented 2 years ago

Is this issue worked on ? when we can expect a preview of it in .NET 7 timeframe?

YordanYanakiev commented 2 years ago

WebASM v. 2.0 is on the go, and we are still arguing if Browsers going to support multithreading.. :'(

danroth27 commented 2 years ago

Is this issue worked on ? when we can expect a preview of it in .NET 7 timeframe?

Yes, it's being worked on primarily in the dotnet/runtime repo: https://github.com/dotnet/runtime/issues/68162. Best estimate currently is we will preview this in Aug.

Cpt-Falcon commented 2 years ago

WebASM v. 2.0 is on the go, and we are still arguing if Browsers going to support multithreading.. :'(

What do you mean, many browsers have supported multithreading forever now? Web assembly has also supported multithreading forever now. Rust web assembly with multi threading works just fine for example.

Xyncgas commented 2 years ago

Is 'allowing await in blazor' affected by this? I can display IAsyncEnumerable currently by creating another buffer then call statehaschanged when IAsyncEnumerable pulls something new (like a callback), however it would be nice if I can just display IAsyncEnumerable directly in blazor

Xyncgas commented 2 years ago

Makes sense, am I correct in assuming it will be purely based on the task pool, so no System.Thread()? The task pool will simply be given access to more threads?

Isn't Task pool also using System.Thread() anyways

SteveSandersonMS commented 2 years ago

Is 'allowing await in blazor' affected by this?

No, it's unrelated. Await already works completely on WebAssembly. Multithreading is about having multiple threads.

Cpt-Falcon commented 2 years ago

Is 'allowing await in blazor' affected by this? I can display IAsyncEnumerable currently by creating another buffer then call statehaschanged when IAsyncEnumerable pulls something new (like a callback), however it would be nice if I can just display IAsyncEnumerable directly in blazor

Like Steve said its unrelated. You can have async await operating on a single thread, where that single thread is switching between different contexts for things like I/O bound tasks. Its no good for CPU bound tasks though, which is where more threads come in. You can have multiple threads running, all with their own async await contexts. Typically in C#, you can use another thread with the Task.Run function, and the task will execute on the thread pool with multiple threads. This will possibly take advantage of multiple cores on your computer, enabling possibly higher throughput. You could also have a situation where the main browser thread is left on its own to be as responsive as possible to user interaction, and a separate "background" thread does the heavier operations that would otherwise slowdown the UI.

I'd love to see the idea of multiple "UI" threads, no idea if that's possible. If you could do parallel rendering of a complex page, for example, multiple complex charts and tables, that could seriously improve the user experience. This was something I did on a complicated WPF project. The application was large and complex with frequently updating user controls, such that when one window was open it would drastically slow down all the other windows that were running because of too many NotifyPropertyChange events happening on one of the UIs. It was considered bad practice at the time, but there was no way around it because it needed frequent real time updates on multiple windows.

React 18 is building around the process of concurrent rendering such that different portions of the UI can be rendered at the same time or offscreen, I hope we see something similar for blazor.

Xyncgas commented 2 years ago

is building around the process of concurrent rendering such that different portions of the UI can be rendered at the same time or offscreen, I hope we see something similar for blazor

Cool, although I would like to see

await foreach(var ele in PullingService())
{
    <div>@ele</div>
}
SteveSandersonMS commented 2 years ago

@Xyncgas To do that, you should make some custom component, something like <AsyncForeach Items="@PullingService"><div>@context</div></AsyncForeach>. We would be unlikely to make await foreach part of Razor's syntax because the semantics are totally wrong - C#'s await foreach doesn't move onto the following code until it's finished awaiting the list, but that would mean you aren't rendering the rest of the UI (all the markup below this block) until then.

Anyway, for any further discussion about "async foreach" (or anything about async), would you be able to open a separate issue so we can keep this one focused on multithreading? Thanks!

Xyncgas commented 2 years ago

Anyway, for any further discussion about "async foreach" (or anything about async), would you be able to open a separate issue so we can keep this one focused on multithreading? Thanks!

I agree, thanks for the response while I would like to add that I discovered there's a component called Virtualized that does the job

mark-branchboston commented 2 years ago

@mkArtakMSFT

WASM 1.0 spec doesn't include real multithreading, and this is the spec we currently target. We expect improvements in this area in the future.

2.0 is available (I think, it says draft but also shows up in their releases) but it doesn't discuss multithreading in simple terms. Have the expected improvements been made?

danroth27 commented 2 years ago

@mark-branchboston We are no longer blocked on missing browser functionality. We expect to preview support for multithreading in Blazor WebAssembly with .NET 7.

LoupaLoupa commented 2 years ago

I am sorry @danroth27 , when you say preview in .net7, it seems like a step back from previous affirmation. What is the difference or impact of previewing versus standard ways? This is a feature that will change things.

Thank you for all your great work, Team!

Enderlook commented 2 years ago

I am sorry @danroth27 , when you say preview in .net7, it seems like a step back from previous affirmation. What is the difference or impact of previewing versus standard ways? This is a feature that will change things.

Thank you for all your great work, Team!

Before a new major version of .NET (i.e: .NET 7) is released, several "previews" are released as features of .NET 7 are being programmed and added into .NET so users can use and tests it.

At the moment, .NET 7 hasn't been released (that will happen in October AFAIK). However, 6 "preview" versions of .NET 7 have already been released.

So the idea is to add multithreading in the next preview (which if everything goes fine, as usually, the feature will also stay in the standard release of .NET 7).

LoupaLoupa commented 2 years ago

Thank you @Enderlook for your answer. I understand the about preview released before the official release, kind of beta builds to test new things. However, I was more inclined to understand the last statement as being previewed in the full release like MAUI was in .net 6, and if it is the case, I am wondering the impact of being a preview in the full release, can it be use in prod, etc.

Cpt-Falcon commented 2 years ago

I am sorry @danroth27 , when you say preview in .net7, it seems like a step back from previous affirmation. What is the difference or impact of previewing versus standard ways? This is a feature that will change things. Thank you for all your great work, Team!

Before a new major version of .NET (i.e: .NET 7) is released, several "previews" are released as features of .NET 7 are being programmed and added into .NET so users can use and tests it.

At the moment, .NET 7 hasn't been released (that will happen in October AFAIK). However, 6 "preview" versions of .NET 7 have already been released.

So the idea is to add multithreading in the next preview (which if everything goes fine, as usually, the feature will also stay in the standard release of .NET 7).

The fact that multithreading will be available soon is very exciting.

danroth27 commented 2 years ago

@LoupaLoupa @Enderlook The .NET runtime team is actively working on enabling multithreading support in the .NET WebAssembly runtime (https://github.com/dotnet/runtime/issues/68162). They have made great progress to the point that it is already partially functional. We expect to ship a .NET 7 preview with multithreading support in the next couple of months. However, there are still plenty of rough edges with the new multithreading support and we don't believe it will be fully ready for production use in time for the .NET 7 release. For this reason, we're planning to ship multithreading support with .NET 7 as a preview feature, similar to how we previously shipped preview support for HTTP/3 for ASP.NET Core in .NET 6.

TylerDM commented 2 years ago

The .NET runtime team is actively working on enabling multithreading support in the .NET WebAssembly runtime (https://github.com/dotnet/runtime/issues/68162). They have made great progress to the point that it is already partially functional. We expect to ship a .NET 7 preview with multithreading support in the next couple of months. However, there are still plenty of rough edges with the new multithreading support and we don't believe it will be fully ready for production use in time for the .NET 7 release. For this reason, we're planning to ship multithreading support with .NET 7 as a preview feature, similar to how we previously shipped preview support for HTTP/3 for ASP.NET Core in .NET 6.

This is extremely disappointing news. But I want to say that one of the main selling points of Dotnet is the very high level of quality that we benefit from each and every day. I respect that the commitment to that quality takes priority over cramming every feature possible into each release. Thank you all for your hard work and commitment to quality, it is very much appreciated.

The main issue I currently have with the lack of threading support is I have no convenient way to de/serialize surprisingly small amounts of JSON without locking up the UI, especially on lower end machines. With threading support, I would just spin up a new background task to do it and await the result with the UI thread. And until .Net 8, well, I'll have to just tell the users it'll be fixed in 2023 and do my best to work around the issue. Though I supposed I could switch to a binary format for internal APIs to reduce the amount of CPU time needed and net wins on the bandwidth side as a bonus, that's not exactly a trivial change and doesn't work for APIs that I have no control over. Are there any options I'm overlooking that don't involve some crazy setup with Web Workers?

hoangdovan commented 2 years ago

@TylerDM Except Web Workers, there is no other option at all. I have to use Web Workers too, while waiting this feature.

dt200r commented 2 years ago

We are in the same predicament wrt json deserialization. We are unable to move away from Wpf and into Blazor (Maui) until multithreading is good to go.

I appreciate all the hard work done to date and am looking forward to trying the previews.

SteveSandersonMS commented 2 years ago

We are unable to move away from Wpf and into Blazor (Maui) until multithreading is good to go.

@dt200r Blazor MAUI doesn't use WebAssembly at all. It already has complete multithreading support.

LoupaLoupa commented 2 years ago

@TylerDM Except Web Workers, there is no other option at all. I have to use Web Workers too, while waiting this feature.

I guess I need to start looking into Web Workers, as November 2023 is so far away, Thank you for posting this, I wasn't aware of this possibility. This might be an example of why a single release a year might not always be the best solution? IMVHO

Again, I understand that Blazor Wasm multithreads needs more time to meet your standards, I appreciate the hard work you put in for a really amazing product!