我正在尝试获得一个非常简单的例子,将订阅的序列输出到文本框中以工作,正如您所期望的那样,在控制台应用程序中这样做没有问题。
我已经尝试了十几种不同的invoke变体,所有这些变体都抛出了相同的跨线程嘶嘶声。
我读到ObserveOnDispatcher可能会做这项工作?但我哪儿也找不到。正如您在下面的代码中所看到的,我已经尝试过ObserveOn,但同样存在问题。
private void button1_Click(object sender, EventArgs e)
{
var source = Observable.Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)).Timestamp();
source.ObserveOn(Scheduler.CurrentThread).Subscribe(x => textBox1.AppendText(x.Value.ToString()));
}
我不明白为什么下面的方法很好;
source.Subscribe(x => MessageBox.Show(x.Value + " - " + x.Timestamp));
然而,将这些值写入文本框需要发脾气。
有什么想法吗?
根据MSDN论坛上使用CurrentThread
调度器的答案
[…]不是指创建查询的线程,而是指执行查询的当前线程。在这方面,它类似于即时调度程序。不同之处在于,CurrentThread调度程序为所有调度的操作使用单个队列,以支持单线程协同多任务处理,而即时调度程序则立即执行调度的操作,而不管之前调度的操作是否仍在执行。
如果使用WPF或Windows窗体,则有专门的方法可以在UI线程上进行观察:ObserveOnDispatcher
和ObserveOn
。
将调度程序传递到Observable.Timer
:
var source = Observable.Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), DispatcherScheduler.Current).Timestamp();
默认情况下,Observable.Timer
使用任务池。一般来说,如果操作员允许您指定调度程序,您应该这样做。