我想使用Reactive Extensions转换一些消息,并在一小段延迟后转发它们。
消息看起来像这样:
class InMsg
{
int GroupId { get; set; }
int Delay { get; set; }
string Content { get; set; }
}
输出看起来像这样:
class OutMsg
{
int GroupId { get; set; }
string Content { get; set; }
OutMsg(InMsg in)
{
GroupId = in.GroupId;
Content = Transform(in.Content); // function omitted
}
}
有几个要求:
给出一个Observable< InMsg>和发送功能:
IObservable<InMsg> inMsgs = ...;
void Send(OutMsg o)
{
... // publishes transformed messages
}
据我所知,我可以使用Select执行转换。
void SetUp()
{
inMsgs.Select(i => new OutMsg(i)).Subscribe(Send);
}
答案 0 :(得分:9)
您可以使用GroupBy
制作IGroupedObservable
,Delay
来延迟输出,并使用Switch
确保较新的值替换其组中的先前值:
IObservable<InMsg> inMessages;
inMessages
.GroupBy(msg => msg.GroupId)
.Select(group =>
{
return group.Select(groupMsg =>
{
TimeSpan delay = TimeSpan.FromMilliseconds(groupMsg.Delay);
OutMsg outMsg = new OutMsg(); // map InMsg -> OutMsg here
return Observable.Return(outMsg).Delay(delay);
})
.Switch();
})
.Subscribe(outMsg => Console.Write("OutMsg received"));
关于实施的说明:如果在发送消息后(即延迟之后)到达,则会启动新的延迟
答案 1 :(得分:2)
.Merge()
结合IObservable<IObservable<OutMsg>>
结果的表达式,如下所示:
对我来说(在.NET Framework 4.6上使用.NET Rx 3.1.1),修复是将.Merge()
添加到最后,如下所示:
var deduplicated = inputs
.GroupBy(input => input)
.Select(group =>
group
.Select(input => Observable.Return(input).Delay(TimeSpan.FromSeconds(5)))
.Switch())
.Merge(); // <-- This is added to combine the partitioned results