为新订阅者发布事件的最后值
本文关键字:事件 最后 新订阅 布事件 | 更新日期: 2023-09-27 18:08:13
我有一个类Foo
,其事件发布FooState
enum。我想把这个事件变成一个可观察对象,为新的订阅者重放最后一个值。
即使没有订阅者,任何新的订阅者都应该获得最后一个值。
public enum FooState
{
Stopped = 0,
Starting = 1,
Running = 2,
}
public delegate void FooEventHandler(object sender, FooEventArgs e);
public class FooEventArgs : EventArgs
{
public FooEventArgs(FooState fooState)
{
this.State = fooState;
}
public FooState State {get; private set;}
}
public class Foo
{
public event FooEventHandler FooEvent;
public void OnFooEvent(FooState state)
{
var fooEvent = FooEvent;
if(fooEvent != null)
{
fooEvent(this, new FooEventArgs(state));
}
}
}
到目前为止,我的尝试围绕着使用Publish
, RefCount
和Replay
。但是,如果我在触发事件后订阅可观察对象,那么我尝试的所有组合都不起作用。
只要有至少一个订阅,Replay(1).RefCount()
就可以工作,但我也需要为第一个晚订阅工作。
var foo = new Foo();
var obs = Observable.FromEventPattern<FooEventHandler, FooEventArgs>(
h => foo.FooEvent += h,
h => foo.FooEvent -= h)
.DistinctUntilChanged()
.Replay(1)
.RefCount();
// Works if this line is uncomented.
//obs.Subscribe(x => Console.WriteLine("Early Subscriber = " + x.EventArgs.State));
foo.OnFooEvent(FooState.Running);
obs.Subscribe(x => Console.WriteLine("Late Subscriber = " + x.EventArgs.State));
有人知道如何用Rx做这个吗?
RefCount
只在第一次订阅后连接。如果你想细粒度地控制连接发生的时间,你应该使用Replay
+ Connect
。
var publishedSource = eventSource.DistinctUntilChanged().Replay(1);
var connection = publishedSource.Connect();
//Subscribe to publishedSource to receive events and dispose of
connection when you are done.
从我的手机上发布的,所以提前为任何语法错误道歉。
Rx正在做正确的事情,将您的事件通知转换为您的流并重播它们,但您要问的是:"为什么当我订阅事件时,我没有得到初始状态"。
事件不是这样工作的。如果我对foo做a +=。FooEvent,我没有得到当前值的立即触发器。只有当它改变时我才会收到通知。正如您所注意到的,'Replay'将重播后续事件,但不提供订阅时的状态。
要解决您的问题,您需要确保在连接流以获得更改通知之前将当前值放入流中。查看Observable.StartWith().
。在. distinctuntilchanged()调用之前执行". startwith (foo.State)"(紧跟在. fromeventpattern之后)