等待Task.Run无法在void内部工作?

时间:2018-04-11 19:30:08

标签: c# naudio

我正在尝试在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在这里不起作用。它直接跳到最后一个块。

2 个答案:

答案 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);
        });
    }