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

ReactiveUI crashes on initialization in a UWP app #1221

Closed
pingzing opened this issue Jan 5, 2017 · 5 comments
Closed

ReactiveUI crashes on initialization in a UWP app #1221

pingzing opened this issue Jan 5, 2017 · 5 comments

Comments

@pingzing
Copy link

pingzing commented Jan 5, 2017

Do you want to request a feature or report a bug?
Bug.

What is the current behavior?
ReactiveUI 7.0 crashes on application start with a TypeInitializationException in UWP apps.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem
Create a new, blank UWP app, and add ReactiveUI 7.0 via NuGet. Add some element to your code in, say, App.xaml that makes use of Reactive UI, like private ReactiveList<string> test = new ReactiveList<string>();.

Observe crash.

What is the expected behavior?
No crashes.

What is the motivation / use case for changing the behavior?
Crashes are bad =)

Which versions of ReactiveUI, and which platform / OS are affected by this issue? Did this work in previous versions of ReativeUI? Please also test with the latest stable and snapshot (http://docs.reactiveui.net/en/contributing/snapshot/index.html) versions.
ReactiveUI 7.0, on Windows 10 Anniversary Update, creating a UWP app. Presumably it worked in previous versions, as I see references to people using it for UWP in 6.5.2.

I see the same issue in the latest snapshot (7.1.0-alpha0003).

Other information (e.g. stacktraces, related issues, suggestions how to fix)

The exception message: Value cannot be null. Parameter name: dispatcher

Here's the stack trace:
Inner Exception:

at System.Reactive.Concurrency.CoreDispatcherScheduler..ctor(CoreDispatcher dispatcher)
at System.Reactive.Concurrency.CoreDispatcherScheduler.get_Current()
at ReactiveUI.PlatformRegistrations.<>c.<Register>b__0_5()
at ReactiveUI.WaitForDispatcherScheduler.attemptToCreateScheduler()
at ReactiveUI.PlatformRegistrations.Register(Action`2 registerFunction)
at ReactiveUI.DependencyResolverMixins.InitializeReactiveUI(IMutableDependencyResolver resolver)
at ReactiveUI.RxApp.<>c.<.cctor>b__0_0()
at Splat.Locator.RegisterResolverCallbackChanged(Action callback)
at ReactiveUI.RxApp..cctor()

Outer Exception:

at ReactiveUI.RxApp.get_MainThreadScheduler()
at ReactiveUI.ReactiveList`1.setupRx(IEnumerable`1 initialContents, Double resetChangeThreshold, IScheduler scheduler)
at ReactiveUI.ReactiveList`1..ctor()
at deleteme_rx_test.App..ctor()
at deleteme_rx_test.Program.<>c.<Main>b__0_0(ApplicationInitializationCallbackParams p)

@ghuntley
Copy link
Member

ghuntley commented Jan 5, 2017

Thank you for the solid bug report. I'm going to look at this first thing in the morning. This shouldn't happen. 😱

@kentcb
Copy link
Contributor

kentcb commented Jan 5, 2017

I have a UWP app that uses Rx 7 without issue, so I was intrigued by this and just did a little investigation.

I can confirm that I can repro the crash if I attempt to use RxUI before OnLaunched. Using RxUI any time after this is fine.

What appears to be happening is that RxUI detects that it is not yet initialized, and does so. This involves creating/resolving schedulers to expose via RxApp.MainThreadScheduler etc. One of those schedulers is a CoreDispatcherScheduler (this is an Rx thing, not RxUI). The static CoreDispatcherScheduler.Current property gets the existing scheduler, or creates one for you. To do so, it needs the current Dispatcher (via Window.Current.Dispatcher in UWP land). Unfortunately, this is null until OnLaunched is called. Hence, CoreDispatcherScheduler.Current throws an exception because it can't create the scheduler.

Not sure there's a whole lot RxUI could do here apart from detect the early init attempt and give a better error message.

@pingzing
Copy link
Author

pingzing commented Jan 9, 2017

That makes sense. From a user PoV, a more specific error message would definitely be welcome, and until a fix is in, a quick note in the docs would be welcome as well.

More generally, I wonder if maybe a delayed initialization through the use of something like a TaskCompletionSource would be an option. It's very common to set up services, dependency injection plumbing, IoC etc. in the app's constructor, and demanding that an app wait to do it's init in OnLaunched could make using ReactiveUI in concert with other things more difficult.

Thanks for the quick reply though!

@olevett
Copy link
Member

olevett commented Feb 14, 2017

Should the WaitForDispatcherScheduler be handling this a bit better? For some platforms, we defer to CurrentThreadScheduler until we can safely resolve an inner scheduler (currently "safely" is "it doesn't throw an InvalidOperationException).

Do we want to

  1. catch the null reference exception thrown by the CoreDispatcherScheduler.Current and rethrow as a user friendly exception to make detecting this easier
  2. catch the null reference exception, and use it as another case to use the CurrentThreadScheduler until we can resolve the platform dependent scheduler when available

It feels like (2) is a more consistent approach, but there's a chance we make it harder to fall into the pit of success in some cases. Maybe there should be some logging kicked out at the point this occurs anyway?

A couple of references for this

  • registering the dispatcher is here
  • where we catch InvalidOperationExceptions is here

olevett added a commit to olevett/ReactiveUI that referenced this issue Mar 7, 2017
On UWP, the dispatcher can fail with an argument null exception if called before OnLoaded.

Fixes reactiveui#1221
@olevett olevett mentioned this issue Mar 7, 2017
3 tasks
olevett added a commit to olevett/ReactiveUI that referenced this issue May 19, 2017
On UWP, the dispatcher can fail with an argument null exception if called before OnLoaded.

Fixes reactiveui#1221
olevett added a commit to olevett/ReactiveUI that referenced this issue May 24, 2017
On UWP, the dispatcher can fail with an argument null exception if called before OnLoaded.

Fixes reactiveui#1221
@stale stale bot closed this as completed Sep 1, 2017
olevett added a commit to olevett/ReactiveUI that referenced this issue Sep 3, 2017
On UWP, the dispatcher can fail with an argument null exception if called before OnLoaded.

Fixes reactiveui#1221
@cabauman
Copy link
Contributor

Ran into this issue today in 8.0 prerelease. Glad I found this issue for an explanation. I guess I'll just move my RxApp calls to OnLaunched, as suggested, until #1312 gets merged.

@lock lock bot added the outdated label Jun 25, 2019
@lock lock bot locked and limited conversation to collaborators Jun 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants