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

[BUG] RxApp.MainThreadScheduler wrong thread on Server-Side Blazor #2344

Open
bergi9 opened this issue Feb 7, 2020 · 7 comments
Open

[BUG] RxApp.MainThreadScheduler wrong thread on Server-Side Blazor #2344

bergi9 opened this issue Feb 7, 2020 · 7 comments

Comments

@bergi9
Copy link

bergi9 commented Feb 7, 2020

I tested DynamicData with Server-Side Blazor in combination with RxUI.
The first Exceptions (System.InvalidOperationException: Collection was modified) came when ReadOnlyObservableCollection<> are accessed in the Blazor's renderer while DD updates the collections (with i.e.: observableChangeSet.observeOn(RxApp.MainThreadScheduler).Bind(out list)...).
The RxApp.MainThreadScheduler obviously doesn't run on the same thread as Blazor's renderer.
After some searching I found that the Dispatcher class exist in Microsoft.AspNetCore.Components.Dispatcher that's may used for the Blazor's renderer.
An explicit scheduler implementation for server-side Blazor might missing?

@bergi9 bergi9 added the bug label Feb 7, 2020
@open-collective-bot
Copy link

open-collective-bot bot commented Feb 7, 2020

Hey @bergi9 👋,

Thank you for opening an issue. We will get back to you as soon as we can. Also, check out our Open Collective and consider contributing financially.

https://opencollective.com/reactiveui

PS.: We offer priority support for all financial contributors. Don't forget to add priority label once you start contributing 😄

An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms!

@glennawatson
Copy link
Contributor

The problem is blazor has a dispatcher per page and not a overall consistent thread for rendering. We might need to rethink rxapp static methods at some stage

@bergi9
Copy link
Author

bergi9 commented Feb 7, 2020

So the solution for now would be a ISchedulerProvider service registered as scoped service if I implement an IScheduler with the dispatcher's class? If then which base class for IScheduler should I take?

@b-straub
Copy link
Contributor

b-straub commented Apr 30, 2020

@bergi9

Can you provide an example illustrating the problem? I have a SPA project using DD as well and made some stress testing for the page rendering but I couldn't reproduce the synchronization problem. Maybe I have solved the StateHasChanged Invokation differently.
Indeed using .ObserveOn(RxApp.MainThreadScheduler) doesn't make sense for Blazor yet.

@jamescarter-le
Copy link

I think I may have encountered this issue.

The application works fine while debugging through VS 2019, Start Debug, but running the application with dotnet run fails to resolve a certain Observable.

@jspuij
Copy link

jspuij commented Oct 9, 2023

For anyone encountering this issue: Blazor Server and Blazor Hybrid provide a synchronization context that can be used to schedule UI updates on. So the following code is usually enough:

.ObserveOn(new SynchronizationContextScheduler(SynchronizationContext.Current))

This code captures the current Synchronization context, so it has to be executed within one of the overridden component lifecycle methods. However typically whenever you create / activate a viewmodel and define observables you are in a calltree that originated from one of the component lifecycle methods, so then it's safe.

If you are not just split the capture and usage of the synchronization context like this:

// capture the context on some render thread code:
var context = SynchronizationContext.Current;

//...

// use the context in some code that defines this observable outside the render thread:
.ObserveOn(new SynchronizationContextScheduler(context))

@NeverMorewd
Copy link

For anyone encountering this issue: Blazor Server and Blazor Hybrid provide a synchronization context that can be used to schedule UI updates on. So the following code is usually enough:

.ObserveOn(new SynchronizationContextScheduler(SynchronizationContext.Current))

This code captures the current Synchronization context, so it has to be executed within one of the overridden component lifecycle methods. However typically whenever you create / activate a viewmodel and define observables you are in a calltree that originated from one of the component lifecycle methods, so then it's safe.

If you are not just split the capture and usage of the synchronization context like this:

// capture the context on some render thread code:
var context = SynchronizationContext.Current;

//...

// use the context in some code that defines this observable outside the render thread:
.ObserveOn(new SynchronizationContextScheduler(context))

I am looking into the same issue in Wpf. This workaround works well!

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

No branches or pull requests

7 participants