包装可能瞬态对象的惯用方法

我正在为控制pulseaudio声音服务器的C库编写一些C#绑定,我不确定如何惯用绑定一些暴露的潜在瞬态对象:特别是接收器。

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

这两个问题都闻到了。 我想提供一些Sink抽象,但我不确定如何避免这些问题。

处于类似情况的其他人如何处理这类问题?

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

有一个API可以对各种有趣的事件进行回调,例如hotplug,因此可以将每个Sink到那个,并至少得到它何时消失的通知。

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

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

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

有趣的读物: 漏洞抽象法则

因此,我的建议不是尝试创建(泄漏)抽象,而只是暴露pulseaudio的概念。

难道你不能只听取HotPlug事件,然后使用您的库将其冒泡到应用程序中吗? 正常的C#模式是为您的Sink类实现INotifyPropertyChanged。

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