我很难理解主题对象。
请考虑以下代码:
var sub = new Subject<int>();
sub.Subscribe(x => Console.WriteLine(x)); //subscriber #1
sub.Subscribe(x => Console.WriteLine(x)); //subscriber #2
sub.OnNext(2);
我正在创建一个int主题,当我执行OnNext时,它会调用其他订阅者(#1和#2)。 我没有得到的是,我读到主题意味着一个既可观察又观察者的对象,但这又如何解释为什么当我调用OnNext时,其他订阅者被调用。
我会理解,如果主题的OnNext会将它传播给所有订阅者=发布给所有其他订阅者(这是有道理的)但是当我检查源代码时我看不到任何有关它的内容,请参阅下文。
有人可以从下面的代码中理解究竟是什么让OnNext(2)传播到其他订阅? (#1,#2)?
public sealed class主题:ISubject,ISubject,IObserver,IObservable,IDisposable { //字段 private volatile IObserver _observer;
// Methods
public Subject()
{
this._observer = NopObserver<T>.Instance;
}
public void Dispose()
{
this._observer = DisposedObserver<T>.Instance;
}
public void OnCompleted()
{
IObserver<T> comparand = null;
IObserver<T> completed = DoneObserver<T>.Completed;
do
{
comparand = this._observer;
}
while (((comparand != DisposedObserver<T>.Instance) && !(comparand is DoneObserver<T>)) && (Interlocked.CompareExchange<IObserver<T>>(ref this._observer, completed, comparand) != comparand));
comparand.OnCompleted();
}
public void OnError(Exception error)
{
if (error == null)
{
throw new ArgumentNullException("error");
}
IObserver<T> comparand = null;
DoneObserver<T> observer3 = new DoneObserver<T> {
Exception = error
};
DoneObserver<T> observer2 = observer3;
do
{
comparand = this._observer;
}
while (((comparand != DisposedObserver<T>.Instance) && !(comparand is DoneObserver<T>)) && (Interlocked.CompareExchange<IObserver<T>>(ref this._observer, observer2, comparand) != comparand));
comparand.OnError(error);
}
public void OnNext(T value)
{
this._observer.OnNext(value);
}
public IDisposable Subscribe(IObserver<T> observer)
{
if (observer == null)
{
throw new ArgumentNullException("observer");
}
IObserver<T> comparand = null;
IObserver<T> observer3 = null;
do
{
comparand = this._observer;
if (comparand == DisposedObserver<T>.Instance)
{
throw new ObjectDisposedException("");
}
if (comparand == DoneObserver<T>.Completed)
{
observer.OnCompleted();
return Disposable.Empty;
}
DoneObserver<T> observer4 = comparand as DoneObserver<T>;
if (observer4 != null)
{
observer.OnError(observer4.Exception);
return Disposable.Empty;
}
if (comparand == NopObserver<T>.Instance)
{
observer3 = observer;
}
else
{
Observer<T> observer5 = comparand as Observer<T>;
if (observer5 != null)
{
observer3 = observer5.Add(observer);
}
else
{
observer3 = new Observer<T>(new ImmutableList<IObserver<T>>(new IObserver<T>[] { comparand, observer }));
}
}
}
while (Interlocked.CompareExchange<IObserver<T>>(ref this._observer, observer3, comparand) != comparand);
return new Subscription<T>((Subject<T>) this, observer);
}
private void Unsubscribe(IObserver<T> observer)
{
IObserver<T> comparand = null;
IObserver<T> instance = null;
Label_0004:
comparand = this._observer;
if ((comparand != DisposedObserver<T>.Instance) && !(comparand is DoneObserver<T>))
{
Observer<T> observer4 = comparand as Observer<T>;
if (observer4 != null)
{
instance = observer4.Remove(observer);
}
else
{
if (comparand != observer)
{
return;
}
instance = NopObserver<T>.Instance;
}
if (Interlocked.CompareExchange<IObserver<T>>(ref this._observer, instance, comparand) != comparand)
{
goto Label_0004;
}
}
}
// Properties
public bool HasObservers
{
get
{
return (((this._observer != NopObserver<T>.Instance) && !(this._observer is DoneObserver<T>)) && (this._observer != DisposedObserver<T>.Instance));
}
}
// Nested Types
private class Subscription : IDisposable
{
// Fields
private IObserver<T> _observer;
private Subject<T> _subject;
// Methods
public Subscription(Subject<T> subject, IObserver<T> observer)
{
this._subject = subject;
this._observer = observer;
}
public void Dispose()
{
IObserver<T> observer = Interlocked.Exchange<IObserver<T>>(ref this._observer, null);
if (observer != null)
{
this._subject.Unsubscribe(observer);
this._subject = null;
}
}
}
}
答案 0 :(得分:1)
我知道但是困扰我的是它没有意义。我进一步深入研究代码,发现他们的观察者内部实现包含更多的观察者,见下文。
如果你检查OnNext方法,你可以看到他们正在迭代所有观察者并调用他们的OnNext方法。
现在一切对我都有意义,我理解了逻辑,却无法看到它的实施位置。
internal class Observer<T> : IObserver<T>
{
private readonly ImmutableList<IObserver<T>> _observers;
public Observer(ImmutableList<IObserver<T>> observers)
{
this._observers = observers;
}
internal IObserver<T> Add(IObserver<T> observer)
{
return new Observer<T>(this._observers.Add(observer));
}
public void OnCompleted()
{
foreach (IObserver<T> observer in this._observers.Data)
{
observer.OnCompleted();
}
}
public void OnError(Exception error)
{
foreach (IObserver<T> observer in this._observers.Data)
{
observer.OnError(error);
}
}
public void OnNext(T value)
{
foreach (IObserver<T> observer in this._observers.Data)
{
observer.OnNext(value);
}
}
internal IObserver<T> Remove(IObserver<T> observer)
{
int index = Array.IndexOf<IObserver<T>>(this._observers.Data, observer);
if (index < 0)
{
return this;
}
if (this._observers.Data.Length == 2)
{
return this._observers.Data[1 - index];
}
return new Observer<T>(this._observers.Remove(observer));
}
}
答案 1 :(得分:0)
主题是可观察的,因为您可以订阅它。你在你的例子中做到了(你确实订阅了两个订阅者)。
主题也是观察者,因为您可以执行以下操作:
someObservable.Subscribe(subject);
这样你的主题就会收到来自someObservable
的事件并将它们传播给自己的订阅者。
P.S。在您的代码中,您自己调用了OnNext()
方法。但这正是someObservable
在您使用主题订阅时所做的事情。