亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

按事件完成 IObservable

按事件完成 IObservable

C#
狐的傳說 2022-06-19 16:33:43
有一種方法可以使用Observable.FromEvent. 例如這個類:class Generator<T>{    event Action<T> onPush;    public IObservable<T> Items =>        Observable.FromEvent<T>(d => onPush += d, d => onPush -= d);    public void Push(T item) => onPush?.Invoke(item);}但是,我還沒有找到一種方法來通過事件來完成 observable - 我該怎么做?更新:為了澄清我的意思,上面的課程產生IObservable<T>了“無盡的”并且永遠不會完成。我想讓它由另一個事件完成,而不是另一個可觀察的。所以問題可以簡化為:如何使任意一個IObservable<T>過早完成,即被OnCompleted調用的通知?
查看完整描述

1 回答

?
不負相思意

TA貢獻1777條經驗 獲得超10個贊

一個 observable 代表一個通知流或事件流。當一個可觀察的來源來自一個事件時,它們本質上是無窮無盡的。observable 連接到事件,引用對象,因此支持事件的對象永遠不會超出范圍。.NET/C# 沒有提供一種方法來指示一個事件將不再被調用,因此直接連接到該事件的 observable 是無窮無盡的。


這并不少見;大多數基于事件的可觀察對象從未OnCompleted明確調用過,而是對現實世界進行建模,在這個世界中很難明確地說某些事情永遠不會再發生。


然而,這不是問題:Observables 意味著無限運行,并且不會造成任何損害。未訂閱的 observable 不會占用太多資源。如果你對事件源 observable 不感興趣,取消訂閱所有訂閱就可以了。


一種方法是使用其中一個Take運算符,例如TakeUntil運算符(如下所述)。嘗試以下代碼(使用您的Generator課程):


var g = new Generator<int>();

g.Items

    .TakeUntil(i => i > 3)

    .Subscribe(

        i => Console.WriteLine($"OnNext: {i}"), 

        e => Console.WriteLine($"OnError: Message: {e.Message}"), 

        () => Console.WriteLine("OnCompleted")

    );


g.Push(1);

g.Push(2);

g.Push(3);

g.Push(4);

g.Push(5);

g.Push(6);

輸出:


OnNext: 1

OnNext: 2

OnNext: 3

OnNext: 4

OnCompleted

TakeUntil在有整數大于 3 的消息后取消訂閱Itemsobservable。這就是為什么有 OnCompleted,沒有 5、6 條消息的原因。


另外,正如 Enigmativity 所提到的,您的Generator<T>課程與 基本相同Subject<T>,我建議您使用它。


原答案:


從事件中制作另一個可觀察的,然后使用.TakeUntil:


class Generator<T>

{

    event Action<T> onPush;

    event Action<Unit> onCompleted;


    public IObservable<T> Items =>

        Observable.FromEvent<T>(d => onPush += d, d => onPush -= d)

        .TakeUntil(Completion);


    public IObservable<Unit> Completion =>

        Observable.FromEvent<Unit>(d => onCompleted += d, d => onCompleted -= d);


    public void Push(T item) => onPush?.Invoke(item);

    public void Complete() => onCompleted?.Invoke(Unit.Default);

}


查看完整回答
反對 回復 2022-06-19
  • 1 回答
  • 0 關注
  • 109 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號