My reactive code (invlolving Throttle
and WhenAnyValue
) is Deadlocking
#3622
Replies: 3 comments 2 replies
-
An update: I have managed to create a smaller example. The view model now looks like this:
This makes the deadlock a bit harder to hit (based on my subjective experience typing random characters into a text field). Changing the throttle timing to 30ms made it a bit easier again, though. In addition, by just trying a bunch of random stuff, I think I have arrived at a solution which appears to make the issue go away both in the minimal example and in the actual code I am trying to build. By defining
I have literally no idea why this works or if it is really a fix, or just makes the timing which causes the deadlock hard enough to hit that I can't trigger it anymore. I would still really like to know why this happens, and how to write code which does not randomly deadlock with reactive UI. I am pretty nervous about this solution because my understanding is that the schedulers can mean different things on different platforms. Will my code deadlock again if I try to use the view model with Blazor WebAssembly instead of server? Or with MAUI? Are there a set of practical rules to follow for using these reactive combinators safely? Is causing deadlocks when you don't do things correctly expected? |
Beta Was this translation helpful? Give feedback.
-
I think what might be happening is that there isn't a deadlock, but an exception that's killing the stream, because the throttling timer occasionally fires outside of the UI's Blazor doesn't employ a literal main UI thread, in the same sense that WPF or other desktop UI frameworks do, but it does employ a "logical" main UI thread, I.E. UI operations are not built to be thread-safe, and operations affecting UI must be synchronized to run serially, which Blazor does with a Regardless of the specifics of this issue, it definitely seems like you should be marshalling that throttled stream back to the "main thread". |
Beta Was this translation helpful? Give feedback.
-
This snippet of code is effectively recreating Some Pro-Tips: // Invoke the command automatically
this.WhenAnyValue(t => t.Start)
.Throttle(TimeSpan.FromMilliseconds(200), RxApp.MainThreadScheduler) // XXX: Always always provide a scheduler!
.InvokeCommand(this, x => x.DoALongThingCommand);
// ...later
// The results of command invocations are themselves Observables, this means you can ToProperty them!
DoALongThingCommand
.ToProperty(this, x => x.Result, out _Result); |
Beta Was this translation helpful? Give feedback.
-
Hello,
I have been using ReactiveUI with Blazor for a while now and run into the following issue. I have tried to make this example as small as possible. As you might be able to tell from the title, I am not really sure what exactly is causing the issue, so I am also not sure if this example is truly minimal.
View model:
blazor view:
And this is what tends happens when I interact with the UI:
deadlock.mp4
As you can see things are working for a while, and then the view model locks up.
This kind of pattern:
Has been my approach to running a function which could take some time asynchronously, with a "loading" value injected into the observable while the program is "thinking". The fact that it is deadlocking seems to indicate that it is not a very good way. I would be grateful to know:
Beta Was this translation helpful? Give feedback.
All reactions