I am encountering an absolutely bizarre behaviour in a Silverlight application on which I am working. Please see the following code:
var replaySubject = new ReplaySubject<string>(1);
replaySubject.OnNext("This can never block... surely?");
var s = replaySubject.First();
Debug.WriteLine(s);
Basically, my app comes through this piece of code repeated and it always prints out the message… except for in one particular scenario in which the thread blocks on the First() line.
It’s always on the UI thread. If I set a break point on the line with First(), and drill into the replaySubject with the debugger, I can see the string in its queue.
Can anyone think of any scenario that would cause the First() call to block here?
BTW: It’s RX version 1.1.11111
OK, so it turns out that by default,
ReplaySubjectuses theScheduler.CurrentThread.If I explicitly set the
ReplaySubjectto useScheduler.ImmediateorScheduler.ThreadPool, then it works as expected.I still need to investigate how it is that the UI thread gets itself into this mess in my particular scenario but for now, this solves the issue.
— edited —
OK, on further investigation, it turns out that the above piece of code for most of the time is initiated on a ThreadPool thread. Even though, when it reaches the code, it is on the Dispatcher thread, Scheduler.CurrentThread puts the ReplaySubject back onto the original ThreadPool thread.
However, in the scenario where it is breaking, everything starts with the user clicking a button. This is obviously on the UI thread, and when it reaches this piece of code, Scheduler.CurrentThread is now the UI thread, and since we are already on the UI thread, we have a deadlock. First is waiting for the ReplaySubject to pump – but the pump is queued up behind the current action. Subtle and something of which to be aware.