-
Notifications
You must be signed in to change notification settings - Fork 10.1k
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
[blazor][wasm] Dispatch rendering to main thread (Net9) #52724
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
src/Components/WebAssembly/WebAssembly/src/Rendering/WebAssemblyDispatcher.cs
Outdated
Show resolved
Hide resolved
src/Components/WebAssembly/WebAssembly/src/Rendering/WebAssemblyDispatcher.cs
Show resolved
Hide resolved
src/Components/WebAssembly/WebAssembly/src/Rendering/WebAssemblyRenderer.cs
Show resolved
Hide resolved
src/Components/WebAssembly/testassets/ThreadingApp/Pages/Counter.razor
Outdated
Show resolved
Hide resolved
src/Components/WebAssembly/testassets/ThreadingApp/Pages/Counter.razor
Outdated
Show resolved
Hide resolved
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
What should happen with |
This comment was marked as resolved.
This comment was marked as resolved.
There's an Artifacts tab in the AzDO view, but I'm not sure who has access. I pulled the trace out of a dump artifact. |
src/Components/WebAssembly/testassets/ThreadingApp/Pages/FetchData.razor
Outdated
Show resolved
Hide resolved
src/Components/WebAssembly/WebAssembly/src/Rendering/WebAssemblyRenderer.cs
Outdated
Show resolved
Hide resolved
a764b18
to
9800678
Compare
Co-authored-by: Steve Sanderson <SteveSandersonMS@users.noreply.github.com>
The extra sophistication you speak about, should be compared with extra methods
I agree that the developer experience of using public API of
If we wanted to have better API for the |
Do we know if this actually ever happens ? We can use
I think it doesn't need to be there. But I can add extra try/catch layer to |
To get a better sense of the compatibility level with existing code, I was hoping to try running the existing suite of E2E tests with the multithreaded wasm runtime. (Note that I only hope to do this as a one-off manual run, not as something to run on every build in CI). However I'm not sure what's required to enable that. What I did, while using the code in this branch:
However at runtime the app doesn't start, as it hits these errors which appear in the browser console:
Are there some additional steps needed to enable the multithreaded runtime properly? Do you know why it would be unable to find these methods? |
If we don't know of a specific reason why it would make a difference, then TBH I'd prefer not to add extra logic for that. If we need to tweak some low-level error handling behavior later then we can do so. |
- propagate cancellation
@SteveSandersonMS It matches what I did in src\Components\WebAssembly\testassets\ThreadingApp\ThreadingApp.csproj, so I'm not sure what's wrong. I guess you have installed the workload ?
This means that you have non-MT assemblies from the runtime pack. The MT runtime pack comes with the workload. Note there is Maybe you need clean/rebuild the test app ? |
I'll try. But if that fixes it, wouldn't it mean there's a framework/SDK bug? Developers should only have to run the "build" gesture to get an up-to-date output. |
If you are using 17.9.x beware of VS accelerated builds might be getting in the way. |
Update: yes, removing |
@SteveSandersonMS yes, but I did that like last week, it probably hasn't reached here yet. Specially if the PR hasn't been rebased recently. |
OK, so I've been running the existing E2E Blazor WebAssembly tests with the MT runtime enabled, and the great majority pass, but a few seem to hit problems:
Would you be able to check into what's going on, so we can be confident both the MT runtime and the new dispatching logic are all working consistently with our other platforms? |
I'm glad you tested this @SteveSandersonMS, thank you.
I expect this to fix or improve with dotnet/runtime#96618
Yeah, I merged your suggestion from GH and only then added the button to trigger it in next commit.
Synchronous dispatch of Making assumptions on if you are or are not on the right thread when you Also in MT, you can't know if any other thread is making the queue busy at any time (X). But I can imagine there are existing code-bases in the wild which work this way and it may bite them.
That would have to be A) If we wanted to check that
I like consistency, which would mean B) But I don't like the sync dispatch assumption especially because (X). That said I agree and prefer @javiercn what do you think ? I would like to note, that this PR is probably not the last bit. There are 2 possible ways how I could do it.
How this is relevant:
|
We would have to also prevent other threads from posting jobs in the meantime, as a race condition. |
Cool, thanks for your feedback.
Great. I'll ignore this aspect then, since it's not Blazor specific, and we will assume the runtime will deal with whatever's necessary to make SignalR Client continue working.
Totally fine with me. We don't actually have to change the test because it's not going to run on the MT runtime. I only made a local change to enable a one-time run, but there's no plan to extend the CI run to do all the E2E tests on both single-threaded and multithreaded runtimes. I agree overall that the synchronous-dispatch-if-idle behavior is best regarded as a perf optimization, not a guaranteed behavior. It totally makes sense for the MT runtime not to do that, because it would be so much more complicated for it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent work! Thanks for being so thorough with the details.
This PR implements
WebAssemblyDispatcher
which will dispatch the call toComponent.InvokeAsync
back to main thread, where all the rendering/JS interop/networking could happen.Context: with
<WasmEnableThreads>true</WasmEnableThreads>
we could use thread pool in C#.Added new
src/Components/WebAssembly/testassets/ThreadingApp
InvokeAsync
to render it.Notes:
RendererSynchronizationContext
is running jobs on multiple threadsJSSynchronizationContext
is running jobs always in single threadRendererSynchronizationContextDispatcher
andWebAssemblyDispatcher
can synchronously run jobs out of order!RendererSynchronizationContextDispatcher
checksSynchronizationContext.Current
which could propagate to multiple threadsWebAssemblyDispatcher
checks explicit thread, because of the JS objects thread affinity.Task
RendererSynchronizationContext
hasUnhandledExceptionEventHandler
WebAssemblyDispatcher
always propagates the exception to the caller.Contributes to dotnet/runtime#85592
Fixes #48768
Fixes dotnet/runtime#95547
Previous attempt #48991