我最近有以下情况"玩Rx" -project:
class Program
{
static void Main(string[] args)
{
var observable1 = Observable.Create<int>(
(Func<IObserver<int>, IDisposable>)GenerateSequence);
var observable2 = Observable.Create<int>(
(Func<IObserver<int>, IDisposable>)GenerateSequence);
var merged = observable1.Merge(observable2);
observable1.Subscribe(i => Console.WriteLine("1: " + i.ToString()));
observable2.Subscribe(i => Console.WriteLine("2: " + i.ToString()));
merged.Subscribe(i => Console.WriteLine("Merged: " + i.ToString()));
Console.ReadLine();
}
private static int count = 0;
private static IDisposable GenerateSequence(IObserver<int> observer)
{
ThreadPool.QueueUserWorkItem((o) =>
{
while (true)
{
observer.OnNext(count++);
Thread.Sleep(500);
}
});
return Disposable.Empty;
}
}
现在,我希望看到像
这样的东西1: 0
2: 1
Merged: 0
Merged: 1
1: 2
2: 3
Merged: 2
Merged: 3
相反,我正在看
1: 0
2: 1
Merged: 2
Merged: 3
1: 4
2: 5
Merged: 6
Merged: 7
如果我用
替换循环while (true)
{
observer.OnNext(r.Next(0, 1000));
Thread.Sleep(500);
}
对于Random的静态或局部实例r,合并后的序列中有两个单独序列的其他数字!
我从count++
的一次调用中看不到r.Next(0, 1000)
或observer.OnNext(...)
如何多次执行。 Merge怎么样我不明白?
P.S。:我试图通过锁定或分离两个线程的循环时间来消除竞争条件,但结果没有改变,因此我将这些尝试排除在外。
编辑:似乎GenerateSequence
被调用了4次,因此4个线程被调整为增加count
。虽然这解释了我所看到的,但我不明白为什么会这样。
答案 0 :(得分:4)
observable1
时,您订阅了Observable.Create(GenerateSequence)
,该GenerateSequence
会调用observable2
并开始循环播放。Observable.Create(GenerateSequence)
时,您订阅了GenerateSequence
,该merged
会调用Observable.Merge(observable1, observable2)
并开始循环播放。observable1
时,您订阅了observable2
,订阅了GenerateSequence
和Publish()
。我们在前两点看到了当你做这些事时会发生什么。最终结果是对var observable1 = Observable
.Create<int>((Func<IObserver<int>, IDisposable>)GenerateSequence)
.Publish();
var observable2 = Observable
.Create<int>((Func<IObserver<int>, IDisposable>)GenerateSequence)
.Publish();
var merged = observable1.Merge(observable2);
observable1.Subscribe(i => Console.WriteLine("1: " + i.ToString()));
observable2.Subscribe(i => Console.WriteLine("2: " + i.ToString()));
merged.Subscribe(i => Console.WriteLine("Merged: " + i.ToString()));
observable1.Connect();
observable2.Connect();
的四次调用。
要获得与您正在寻找的效果非常接近的效果,您需要查看observable1
:
observable2
IConnectableObservable
和IObservable
现在属于Observable.Create
类型,这意味着他们不会订阅他们的基础Connect
(在您的情况下为1: 0
Merged: 0
2: 1
Merged: 1
1: 2
Merged: 2
2: 3
Merged: 3
...
),直到他们已调用{{1}}。
输出
{{1}}