How to get WinForm sync context or schedule in WinForm stream

I have a winform application and the observed setup looks like this:

Form form = new Form(); Label lb = new Label(); form.Controls.Add(lb); Observable.Interval(TimeSpan.FromSeconds(1)) .Subscribe(l => lb.Text = l.ToString()); Application.Run(form); 

This does not work, since l => lb.Text = l.ToString() will not start in the main thread that created the form, but I cannot figure out how to make it work in this thread. I suppose I should use IObservable.SubscribeOn , which accepts either IScheduler or SynchronizationContext , but I don’t know how to get the synchronous text of the main thread, and the only schedulers I could find were static Scheduler properties like Scheduler.CurrentThread , Immediate , NewThread , TaskPool and ThreadPool , none of which worked.

My version of Rx is 1.0.10621.

+12
winforms system.reactive synchronizationcontext
Sep 14 2018-11-11T00:
source share
1 answer

Immediately after posting the question, I will find a solution:

 Form form = new Form(); Label lb = new Label(); form.Controls.Add(lb); Observable.Interval(TimeSpan.FromSeconds(2)) .ObserveOn(SynchronizationContext.Current) .Subscribe(l => lb.Text = l.ToString()); Application.Run(form); 

This link has been helpful. Two notes:

  • Not all threads have a synchronization context, but the first form created in the stream will set the synchronization context for this thread, so the UI thread always has one.
  • The correct ObserveOn method, not SubscribeOn . At the moment, I don’t know enough about this to know why, so any links in the comments will be appreciated.



edit: Thanks to the first part of this link, I now more understand the difference between ObserveOn and SubscribeOn . In short:

  • Observable, observable in the context of synchronization, will call the IObserver methods ( OnNext and friends) from this context. In my example, I am observing the main / user interface thread, so therefore I do not see exceptions for cross-threads
  • SubscribeOn bit more complicated, so here is an example: Concat takes a series of observables and combines them into one long observable. As soon as OnCompleted calls are OnCompleted , combined observables will dispose of this subscription and subscribe to the next observable. All this happens in a thread called OnCompleted , but there may be problems subscribing to observables that were created by Observable.FromEvent , for example. Silverlight will throw if you add an event handler from a thread other than the user interface thread, and WinForms and WPF will throw if you add event handlers from several different threads. SubscribeOn allows you to control the flow on which your observed bindings fall into the main event.
+23
Sep 14 2018-11-14T00:
source share



All Articles