winforms – 如何在WinForm线程上获取WinForm同步上下文或计划

我有一个winform应用程序,一个可观察的设置如下:

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);

这不起作用,因为l => lb.Text = l.ToString()不会在创建表单的主线程上运行,但是我无法弄清楚如何使其在此线程上运行.我假设我应该使用IObservable.SubscribeOn,它需要一个IScheduler或SynchronizationContext,但是我不知道如何获取主线程的synchronizedcontext,我可以找到的唯一的Scheduler是Scheduler的静态属性,作为Scheduler.CurrentThread,立即,NewThread,TaskPool和ThreadPool,其中没有一个工作.

我的Rx版本是1.0.10621.

刚刚发布问题后,我找到解决方案:

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链接是有帮助的.两个笔记:

>并非所有线程都具有同步上下文,但是在线程上创建的第一种形式将为该线程设置同步上下文,因此UI线程始终具有一个.
>正确的方法是ObserveOn,而不是SubscribeOn.目前,我不知道为什么这么做,所以评论中的任何链接都将不胜感激.

编辑:感谢this的第一部分链接,我现在更多地了解ObserveOn和SubscribeOn之间的区别.简而言之:

>一个可观察的,在同步上下文中观察到的将从该上下文中调用IObserver方法(OnNext和朋友).在我的例子中,我观察主/ UI线程,所以我没有得到任何交叉线程异常
> SubscribeOn有点复杂,所以这里就是一个例子:Concat需要一些可观察结果,并将它们组合到一个可观察的长度上.一旦可观察的调用OnCompleted,组合的observable将处理该订阅,并订阅下一个observable.这一切都发生在调用OnCompleted的线程上,但是由Observable.FromEvent创建的可观察值可能存在一些问题,例如.如果从另一个线程添加一个事件处理程序,而不是UI线程,Silverlight将抛出,如果从多个不同的线程添加事件处理程序,WinForms和WPF将抛出. SubscribeOn将允许您控制您的可观察挂钩到底层事件的线程.

翻译自:https://stackoverflow.com/questions/7417978/how-to-get-a-winform-synchronization-context-or-schedule-on-a-winform-thread

转载注明原文:winforms – 如何在WinForm线程上获取WinForm同步上下文或计划