如何获得一个WinForm同步上下文或计划在一个WinForm线程 [英] How to get a WinForm synchronization context or schedule on a WinForm thread
问题描述
我有一个WinForm的应用程序,可观察到的设置如下:
I have a winform application, and an observable set up 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);
这是不行的,因为 L => lb.Text = l.ToString()
将不会被其创建的窗体的主线程上运行,但我无法弄清楚如何使它在这个线程上运行。我想,我应该用 IObservable.SubscribeOn
这需要要么是 IScheduler
或的SynchronizationContext
,但我不知道如何让主线程的SynchronizationContext的,唯一的调度程序,我能找到是计划
的静态属性如 Scheduler.CurrentThread
,立即
, NewThread
, TaskPool
和线程池
,其中没有工作。对
This doesn't work, since the l => lb.Text = l.ToString()
will not be run on the main thread which created the form, but I cannot figure out how to make it run on this thread. I assume, that I should use IObservable.SubscribeOn
which takes either an IScheduler
or a SynchronizationContext
, but I don't know how to get the synchronizationcontext of the main thread, and the only Schedulers I could find were the static properties of Scheduler
, such as Scheduler.CurrentThread
, Immediate
, NewThread
, TaskPool
and ThreadPool
, none of which worked.
我接收的版本是1.0.10621。
My Rx version is 1.0.10621.
推荐答案
就在我发帖的问题,我找到了解决办法:
Just after I post the question, I find the 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 was helpful. Two notes:
- 不是所有的线程都同步环境,但得到的线程创建将设置一个同步上下文线程的第一种形式,所以在UI线程总是有一个。
- 在正确的方法是
ObserveOn
,不是SubscribeOn
。此刻,我不知道有足够的了解这个知道为什么,所以在评论中的任何链接将AP preciated。
- Not all threads have a synchronization context, but the first form that gets created on a thread will set a synchronization context for that thread, so the UI thread always has one.
- The correct method is
ObserveOn
, notSubscribeOn
. At the moment, I don't know enough about this to know why, so any links in the comments would be appreciated.
编辑:多亏了第一部分<一个href="http://blogs.msdn.com/b/rxteam/archive/2009/11/21/observable-context-observable-subscribeon-and-observable-observeon.aspx">this链接,现在我更了解的 ObserveOn
和 SubscribeOn
的区别。简而言之:
edit: Thanks to the first part of this link, I now understand more about the difference between ObserveOn
and SubscribeOn
. In short:
- 可观察,观察它在同步上下文将调用来自这方面的IObserver方法(
OnNext
和朋友)。在我的例子,我观察主/ UI线程上,所以因此我没有得到任何的交叉线异常 -
SubscribeOn
是一个有点复杂,所以这里有一个例子:Concat的需要一定数量观测,并将其结合到一个长观测。一旦观察到的电话OnCompleted
,合并后的观察到将部署的认购,并订阅到下一个观察的。这一切都发生了所谓的OnCompleted
的线程上,但可以有一些问题订阅观测,由Observable.FromEvent $创建的C $ C>,例如:如果从另一个线程比UI线程添加事件处理程序的Silverlight将抛出,和WinForms,如果您从多个不同的线程添加事件处理WPF将抛出。
SubscribeOn
将让你控制线程 在这你可观察到挂钩到底层的事件。
- An observable, which observes on a synchronization context will call the IObserver methods (
OnNext
and friends) from that context. In my example, I observe on the main/UI thread, so therefore I get no cross thread exceptions SubscribeOn
is a little more complicated, so here is an example: Concat takes a number of observables and combines them to one long observable. Once an observable callsOnCompleted
, the combined observable will dispose of that subscription, and subscribe to the next observable. This all happens on the thread that calledOnCompleted
, but there can be some problems with subscribing to observables, that were created byObservable.FromEvent
, e.g. Silverlight will throw if you add an event handler from another thread than the UI thread, and WinForms and WPF will throw if you add a event handlers from multiple different threads.SubscribeOn
will let you control the thread on which your observable hooks up to the underlying event.
这篇关于如何获得一个WinForm同步上下文或计划在一个WinForm线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!