从 AVAudioEngine(同步)代码调用 swift Actor

问题描述 投票:0回答:1

我正在使用苹果的 AVAudioEngine 代码,如下所示:

var audioEngine = AVAudioEngine()
audioEngine.inputNode.installTap { [buffer, when] in
   let waveform = myGetWaveform(buffer)
   Task {
      await Something.shared.doSomethingWith(waveform)
   }
}

installTap 的闭包将在某个音频线程上执行。

我这样做是因为

Something
是一个
actor
,而且我很难改变它。但当然,问题是那些
Task
可能会乱序执行。那会很糟糕 - 我需要它们按顺序执行。如何保证它们按顺序执行?我想这可以应用于任何无法将调用者更改为异步的同步代码。我似乎找不到任何方法将序列化注入异步参与者代码中。

发现的许多版本(使用信号量等)似乎都打破了异步的“线程必须向前移动”契约...

澄清:

    我忘记了
  1. await
    ,抱歉。
  2. 当您在 inputNode 上调用 installTap 时,您将传递一个回调闭包。然后,当 inputNode 启动时,它将每秒多次调用给定的闭包。
  3. buffer
     将包含从设备麦克风采样的音频波形数据。这就是难题:在我给出的实现中,每个新的音频缓冲区都会一遍又一遍地调用 
    doSomethingWith
    ,但不一定会按顺序调用。
swift multithreading concurrency actor avaudioengine
1个回答
0
投票
这可以通过实验性的

ClosureIsolation 功能实现,该功能应该很快就会出现在 Swift 6 中。

如果您等不及使用此功能的 Swift 版本,那么您最好的工具是

AsyncStream。您将yield

消息发送到流,Actor 将循环使用它们。

您的 Actor 需要提供一个包含流的

nonisolated

 属性,以便您的同步代码可以访问它。

© www.soinside.com 2019 - 2024. All rights reserved.