代码之家  ›  专栏  ›  技术社区  ›  RAOF

包装可能短暂的对象的惯用方法

c#
  •  0
  • RAOF  · 技术社区  · 6 年前

    我正在为控制Pulseaudio Sound服务器的C库编写一些C绑定,我不确定如何以惯用方式绑定暴露在外的一些可能短暂的对象:特别是接收器。

    Pulseaudio有一个音频接收器的概念——一个给定的音频流正在播放的硬件。这自然会映射到 Sink 类,具有一些明显的属性-体积等。问题是热插拔-音频硬件可以在运行时来来去去去,因此 对象最终可能会变成僵尸,引用不存在的硬件,对它们执行的所有操作都将失败。更糟糕的是,C库没有为接收器提供唯一的句柄,因此一系列热插拔事件可能会改变给定的硬件 实例实际上是在不注意代码的情况下控制的。

    这两个问题都有味道。我想提供一些 抽象,但我不知道如何避免这些问题。

    在类似情况下,其他人是如何处理这类问题的?

    编辑: 在C库中,您似乎只是希望在查询接收器和尝试更改其属性之间不会发生热插拔事件。接收器在API中由索引标识,但这不稳定。每个接收器也有一个标识符字符串,我认为它是唯一的,至少对于每次运行是唯一的。

    有一个API可以获取各种有趣事件的回调,例如热插拔,因此可以连接每个事件 至少在它消失的时候得到通知。

    3 回复  |  直到 15 年前
        1
  •  1
  •   dtb    15 年前

    我认为您应该尝试将C库的这种行为传达给C库的用户。

    我不熟悉Pulseaudio,但根据您提供的唯一标识符的信息,可以设计一个 Sink 类可以如下所示:

    /// <summary>
    /// Represents a sink. May refer to different hardware.
    /// </summary>
    public class Sink
    {
        public static IEnumerable<string> GetCurrentIdentifiers() { ... }
    
        public static Sink GetSinkForIdentifier(string identifier) { ... }
    
        private Sink() { ... }
    }
    

    有趣的阅读: The Law of Leaky Abstractions

    因此,我的建议不是尝试创建一个(泄漏的)抽象,而是简单地公开Pulseaudio的概念。

        2
  •  0
  •   vanja.    15 年前

    难道你不能听一下热插拔事件,然后用你的库将它冒泡到应用程序中去吗?正常的C模式是为水槽类实现inotifyPropertiesChanged。

        3
  •  0
  •   Paul Betts    15 年前

    如果Pulseaudio没有通知您硬件事件,那么处理这种情况从根本上来说是站不住脚的。你需要在PA的C库中编写一些补丁来优雅地处理这个问题,尽管我很惊讶PA没有公开任何方式来处理热插拔设备。