gpt4 book ai didi

c# - ObserveOn with Scheduler.NewThread 不这么观察,如果observer的OnNext被阻塞继续

转载 作者:太空宇宙 更新时间:2023-11-03 11:36:36 27 4
gpt4 key购买 nike

有人可以帮助解释为什么当我“阻塞并继续”观察者的 onNext 序列订阅了一个具有时间可观察序列的缓冲区时,Scheduler.NewThread 不再适用吗?

例如:

如果我通过缓冲一个数字序列

var query = from number in Enumerable.Range(1,200)
select SnoozeNumberProduction(number);

var observableQuery = query.ToObservable();
var bufferedSequence = observableQuery.Buffer(TimeSpan.FromSeconds(2));

SnoozeNumberProduction 将数字生成延迟 250 毫秒

static int SnoozeNumberProduction(Int32 number)
{
Thread.Sleep(250);
return number;
}

现在,如果我使用“ObserveOn(Scheduler.NewThread)”订阅 bufferedSequence,那么我将使用 Console.ReadKey 阻塞在第四个缓冲区上

Random random = new Random();
Int32 count = 0;
bufferedSequence.ObserveOn(Scheduler.NewThread).Subscribe(list =>
{
Console.WriteLine("({0}) Numbers from {1}-{2} produced on Thread ID {3}", list.Count, list[0], list[list.Count -1], Thread.CurrentThread.ManagedThreadId);

Thread.Sleep(1000);
count++;
if (count == 4)
{
Console.WriteLine("count reached to 4, blocking ... press any key to continue ");
Console.ReadKey(); // Block and build up the queue
}

Console.WriteLine("Woken " + list[0] + " - " + list[list.Count - 1]);
});

在这种情况下,如果我在大约 10 秒后按下任意键,我会看到接下来的几个缓冲区在同一个 ManagedThread 上执行,即使在 ObserveOn 中提到了 Scheduler.NewThread 也是如此。有人可以帮助解释这种行为吗?

示例输出:

(7) Numbers from 1-7 produced on Thread ID 12
Woken 1 - 7
(9) Numbers from 8-16 produced on Thread ID 14
Woken 8 - 16
(8) Numbers from 17-24 produced on Thread ID 15
Woken 17 - 24
(8) Numbers from 25-32 produced on Thread ID 16
count reached to 4, blocking ... press any key to continue
Woken 25 - 32
(8) Numbers from 33-40 produced on Thread ID **16**
Woken 33 - 40
(8) Numbers from 41-48 produced on Thread ID **16**
Woken 41 - 48
(8) Numbers from 49-56 produced on Thread ID **16**
Woken 49 - 56
(8) Numbers from 57-64 produced on Thread ID **16**
Woken 57 - 64
(8) Numbers from 65-72 produced on Thread ID **16**
Woken 65 - 72
(8) Numbers from 73-80 produced on Thread ID **16**
Woken 73 - 80
(8) Numbers from 81-88 produced on Thread ID **16**
Woken 81 - 88
(8) Numbers from 89-96 produced on Thread ID **16**

最佳答案

ObserveOn 本身是组合序列中的一个层,唯一的工作就是切换到另一个调度程序。但是,您的 sleep 发生在发生在 IEnumerable 上的 Select 中。然后使用 ToObservable 将该序列转换为 IObservable,默认为 Dispatcher.CurrentThread

只有在这一点上,您才为进入的每个项目交换到另一个线程。如果将其更改为:

var query = from number in Enumerable.Range(1,200).ToObservable(Dispatcher.NewThread)
select SnoozeNumberProduction(number);

var bufferedSequence = query.Buffer(TimeSpan.FromSeconds(2));

现在 枚举 出现在一个新线程上,并且由于您没有做任何改变它的事情,它将留在那里。

实际上有一个 Observable.Range,它以 IObservable 开始,并采用可选的 IDispatcher。但是,我假设您的来源实际上不是 Enumerable.Range。如果是,这是等效的:

var query = from number in Observable.Range(1,200, Dispatcher.NewThread)
select SnoozeNumberProduction(number);

var bufferedSequence = query.Buffer(TimeSpan.FromSeconds(2));

关于c# - ObserveOn with Scheduler.NewThread 不这么观察,如果observer的OnNext被阻塞继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6080004/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com