我正在为控制pulseaudio声音服务器的C库编写一些C#绑定,我不确定如何惯用绑定暴露的一些潜在的瞬态对象:特别是接收器。
pulseaudio具有音频接收器的概念 - 给定音频流的硬件正在播放。这自然会映射到Sink
类,具有一些明显的属性 - 音量等。问题是热插拔 - 音频硬件可以在运行时进出,因此这些Sink
对象可能最终成为僵尸引用不存在的硬件,并且对它们执行的所有操作都将失败。更糟糕的是,C库没有为接收器提供唯一的句柄,因此一系列热插拔事件可能会改变给定Sink
实例实际控制的硬件,而无需代码注意。
这两个问题都闻到了。我想提供一些Sink
抽象,但我不确定如何避免这些问题。
处于类似情况的其他人如何处理这类问题?
在C库中出现编辑:,您只希望在查询接收器和尝试更改其属性之间不会发生热插拔事件。通过索引在API中标识接收器,但这不稳定。每个接收器还有一个标识符字符串,我认为这是唯一的,至少每次运行都是如此。
有一个API可以对各种有趣的事件进行回调,例如hotplug,因此可以将每个Sink
连接到那个,并至少得到它何时消失的通知。
答案 0 :(得分:1)
我认为您应该尝试将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的概念。
答案 1 :(得分:0)
难道你不能只听取HotPlug事件,然后使用您的库将其冒泡到应用程序中吗?正常的C#模式是为您的Sink类实现INotifyPropertyChanged。
答案 2 :(得分:0)
如果PulseAudio没有通知您硬件事件,那么处理这种情况从根本上说是站不住脚的。你需要在PA的C库中编写一些补丁来优雅地处理这个问题,但我很惊讶PA没有任何方式暴露任何处理hotplug设备的方法。