我正在尝试在waveOut.play()上运行“await Task.Run”。原因是我想要这样做是因为我需要在waveOut.play()完成后立即删除文件。但是,我无法删除已经在使用的东西,这就是为什么我需要使用await task.run,但这次似乎不起作用。这可能是重复但我无法找到任何理由为什么程序不等待它完成。
public async void PlayAudio(object sender, GenericEventArgs<Stream> args)
{
fileName = $"{ Guid.NewGuid() }.wav";
using (var file = File.OpenWrite(Path.Combine(Directory.GetCurrentDirectory(), fileName)))
{
args.EventData.CopyTo(file);
file.Flush();
}
WaveOut waveOut = new WaveOut();
WaveFileReader reader = new WaveFileReader(fileName);
waveOut.Init(reader);
try
{
await Task.Run(() =>
{
waveOut.Play();
});
}
finally
{
File.Delete(fileName);
}
}
程序按字符串名称查找文件并播放它。 await task.run在这里不起作用。它直接跳到最后一个块。
答案 0 :(得分:5)
问题是WaveOut.Play()
立即返回。直接从NAudio documentation(强调我的):
开始播放
现在我们已准备好开始播放,我们只需在输出设备上调用Play即可。 值得注意的是,这不是阻止通话。它只是开始播放。如果您希望在播放结束时收到通知,我们将很快讨论如何做到这一点。
waveOut.Play();
因此,您的Task
即刻完成,无需等待播放剪辑。 NAudio文件继续:
停止播放
默认情况下,输出设备(在我们的例子中为WaveOutEvent)将继续播放,直到我们到达传入Init的输入流的末尾。当IWaveProvider.Read方法返回0时,会指示这一点。假设您传入了Mp3FileReader或其他文件阅读器,那么您的文件最终将到达终点。
您可以通过订阅PlaybackStopped事件获得播放已完成的通知。此事件还可以告诉您播放是否因声卡错误而停止。例如,如果您的设备是USB耳机,并且在播放过程中途将其拔下,那么您将看到其中一个错误。
waveOut.PlaybackStopped += OnPlaybackStopped;
您当然可以通过调用Stop来随时请求停止播放。请注意,此方法退出时实际上可能无法停止播放。您只是要求播放停止,而且通常很快就会发生。但只有当你收到PlaybackStopped事件时才能确定它已经完全停止。
waveOut.Stop();
答案 1 :(得分:0)
我用TypelA帮助解决了这个问题。他为我提供了有价值的信息,以确定需要做些什么。这是与我原始问题中的代码相比的最终结果。
public void PlayAudio(object sender, GenericEventArgs<Stream> args)
{
fileName = $"{ Guid.NewGuid() }.wav";
using (var file = File.OpenWrite(Path.Combine(Directory.GetCurrentDirectory(), fileName)))
{
args.EventData.CopyTo(file);
file.Flush();
}
waveOut = new WaveOut();
reader = new WaveFileReader(fileName);
waveOut.Init(reader);
waveOut.PlaybackStopped += OnPlayStopped;
waveOut.Play();
}
private async void OnPlayStopped(object sender, StoppedEventArgs e)
{
Console.WriteLine("Done");
await Task.Run(() =>
{
reader.Dispose();
waveOut.Dispose();
File.Delete(fileName);
});
}