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

时间:2009-11-24 02:32:14

标签: c#

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

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

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

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

在C库中出现

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

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

3 个答案:

答案 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设备的方法。