所以有可能我最終會遇到以下代碼的幾個問題,也許是因爲我使用了Subject
,我不確定它是否可以使用。當我需要選擇許多可觀察對象時,我是否正確思考?
這很難讓我解釋,我不知道爲什麼,也許我缺乏術語。
我想要做的是有一個類型,它可以註冊幾個觀察對象,所以我可以傳遞這個類型,並將所有觀察對象組合在一起,並從中展示一個可觀察對象。
所以我的第一個問題我感覺我沒有以正確的方式思考事情,我想知道這是正確的還是存在一種更「反應性」的方式?
我的意思是,我有這個類型,你可以註冊觀測,也該類型不同,就會暴露出單一可觀察,我也可以訂閱。
我會盡量用下面的代碼示例來解釋一下。 因此,SomeTypeWithObservable
可能是多種類型中的一種,它們將公開IObservable<SomeEvents>
ReactiveTesting
類型是嘗試將所有觀測值組合在一起並暴露單個IObservable<SomEvents>
的類型。有一個RegisterObservable
方法將發送到內部Subject<IObservable<SomeEvents>>
。構造函數將Observable設置爲我想公開的這個主題的SelectMany
。
使用下面的執行,在ReactiveTesting
構造我進行SelectMany.Publish.RefCount
,與虛擬訂閱之後,開始觀察到的,我發現,如果我沒有用假認購不使用可觀的註冊。
所以我第二個問題是代碼行有一個虛擬的訂閱開始可觀察到的,或者我應該做的我做了下面的評論,我剛剛從發表一個連接,然後連接後立即,或者他們都是錯誤的,在這種情況下,有人能指出我的方向是正確的嗎?
我第三個問題我應該使用一個主題?
如果我打電話RegisterObservable
早於訂閱,如果我不把在虛擬Subscribe
或Connect
那麼我不會觀察者觸發任何事件。
我四問題有人能解釋一下後者好嗎? 我有種想法,因爲它是Publish
和RefCount
那麼在訂閱以Observable開始之前沒有什麼可做的。
代碼
--Edited - 要顯示有不止一個可觀察我想在ReactiveTesting
enum SomeEvents
{
event1,
event2,
event3,
event4
}
interface ISomeTypeWithObservable
{
IObservable<SomeEvents> SomeObservableEvents { get; }
}
class SomeTypeWithObservable2 : ISomeTypeWithObservable
{
private event EventHandler SpecialEvent;
public SomeTypeWithObservable2()
{
var observableFromSpecialEvent = Observable.FromEventPattern(h => SpecialEvent += h, h => SpecialEvent -= h).Select(x => SomeEvents.event2);
SomeObservableEvents = Observable.Create<SomeEvents>(observer =>
{
return observableFromSpecialEvent.Subscribe(observer);
})
.Publish()
.RefCount();
}
public IObservable<SomeEvents> SomeObservableEvents { get; }
public void TriggerEvent()
{
SpecialEvent.Invoke(this, new EventArgs());
}
}
class SomeTypeWithObservable : ISomeTypeWithObservable
{
private event EventHandler SpecialEvent;
public SomeTypeWithObservable()
{
var observableFromSpecialEvent = Observable.FromEventPattern(h => SpecialEvent += h, h => SpecialEvent -= h).Select(x => SomeEvents.event1);
SomeObservableEvents = Observable.Create<SomeEvents>(observer =>
{
return observableFromSpecialEvent.Subscribe(observer);
})
.Publish()
.RefCount();
}
//Some code in here that will produce things to observe, maybe Observable.FromEventPattern...
public IObservable<SomeEvents> SomeObservableEvents { get; }
public void TriggerEvent()
{
SpecialEvent.Invoke(this, new EventArgs());
}
}
class ReactiveTesting
{
private Subject<IObservable<SomeEvents>> _innerEvents = new Subject<IObservable<SomeEvents>>();
public IObservable<SomeEvents> AllEvents;
public ReactiveTesting()
{
AllEvents = _innerEvents.SelectMany(x => x).Publish().RefCount();
AllEvents.Subscribe(next => { }, exception => { },() => { });
//This instead of the above??
//var connectableObservable = _innerEvents.SelectMany(x => x).Publish();
//AllEvents = connectableObservable;
//connectableObservable.Connect();
}
public void RegisterObservable(ISomeTypeWithObservable someTypeWithObservable)
{
_innerEvents.OnNext(someTypeWithObservable.SomeObservableEvents);
}
}
class Program
{
static void Main(string[] args)
{
var reactiveTesting = new ReactiveTesting();
var someTypeWithObservable = new SomeTypeWithObservable();
var someTypeWithObservable2 = new SomeTypeWithObservable2();
reactiveTesting.AllEvents.Subscribe(next => Console.WriteLine(string.Format("Subscriber 1 - {0}", next.ToString("G"))));
reactiveTesting.AllEvents.Subscribe(next => Console.WriteLine(string.Format("Subscriber 2 - {0}", next.ToString("G"))));
reactiveTesting.RegisterObservable(someTypeWithObservable);
reactiveTesting.RegisterObservable(someTypeWithObservable2);
someTypeWithObservable.TriggerEvent();
someTypeWithObservable.TriggerEvent();
someTypeWithObservable.TriggerEvent();
someTypeWithObservable2.TriggerEvent();
someTypeWithObservable2.TriggerEvent();
someTypeWithObservable2.TriggerEvent();
Console.WriteLine("Press key...");
Console.ReadLine();
}
}
非常感謝您的回答:-)我想我可能不清楚我想做什麼。我希望能夠用'ReactiveTesting'來註冊許多觀察對象所以'ReactiveTesting'基本上是一個單例,並且可以將所有這些觀察對象組合起來併產生1個。也許我沒有以正確的方式考慮這個與Rx相關的解決方案。此外,訂閱可能發生在我註冊/合併一個新的observable之前。我以爲我會使用發佈,所以我可以訂閱比註冊晚,並仍觀察相同的觀察。 – RichardWilliams