【问题标题】:Generate a second follow up Event with delay for each Event with Rx使用 Rx 为每个事件生成第二个延迟事件
【发布时间】:2017-03-06 13:48:10
【问题描述】:

目前我正在研究使用响应式框架处理 MIDI 消息。

当生成 NoteOn 事件时,它必须跟在 NoteOff 事件之后。那么,在每个 NoteOn 之后以一定的延迟发送第二个事件的最佳方式是什么?

类似:

//pseudo code
var noteOnObservable = GetNoteOns();
var noteOffObservable = noteOnObservable.ForEach(e => new NoteOffMessage(e.MidiNote))
     .Delay(e => GetDelay(e));
var notes = noteOnObservable.Merge(noteOffObservable);

NoteOn 和 NoteOff 消息属于同一类型 MidiMessage

【问题讨论】:

    标签: c# .net linq system.reactive


    【解决方案1】:

    与您拥有的几乎完全一样。理想情况下,您会发布noteOnObservable,这样您就没有多个订阅:

    var noteOnObservable = GetNoteOns().Publish().RefCount();
    var noteOffObservable = noteOnObservable
        .Select(e => new NoteOffMessage(e.MidiNote))
        .Delay(e => GetDelay(e));
    var notes = noteOnObservable.Merge(noteOffObservable);
    

    您没有描述GetDelay 返回的类型。如果它返回一个TimeSpan,那么你必须将它转换为一个可观察的。如果你可以在GetDelay 中工作。如果没有,那么你可以这样做:

    var noteOnObservable = GetNoteOns().Publish().RefCount();
    var noteOffObservable = noteOnObservable
        .Select(e => new NoteOffMessage(e.MidiNote))
        .Delay(e => Observable.Timer(GetDelay(e)));
    var notes = noteOnObservable.Merge(noteOffObservable);
    

    【讨论】:

    • 不知道我离得这么近。感谢 Publish().RefCount() 改进。 GetDelay 尚未指定……这是下一个任务。 Observable.Timer 会为每个事件单独延迟工作吗?
    • 是的。如果你想指定一个静态的TimeSpan(对所有事件统一),那么你可以只做.Delay(TimeSpan.FromMilliseconds(100))或者任何合适的时间。
    • @Shlomo - 稍微简洁的方法是这样做:var notes = GetNoteOns().Publish(gnos => gnos.Merge(gnos.Select(e => new NoteOffMessage(e.MidiNote)).Delay(e => GetDelay(e))));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    相关资源
    最近更新 更多