await Task.Run 不在 void 中工作?
await Task.Run isn't working inside void?
我正在尝试 运行 在我的 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 在这里不起作用。它直接跳到 finally 块。
问题是 WaveOut.Play()
returns 马上。直接来自 NAudio documentation(强调我的):
Starting playback
Now we're ready to begin playback, and we can do so by simply calling Play on our output device. It's important to note that this is not a blocking call. It just begins playback. If you want to be notified when playback ends, we'll discuss how to do that shortly.
waveOut.Play();
因此,您的 Task
会立即完成,无需等待剪辑播放。 NAudio 文档继续:
Stopping playback
By default, the output device (WaveOutEvent in our case) will keep playing until we reach the end of the input stream we passed into Init. This is indicated when the IWaveProvider.Read method returns 0. Assuming you passed in an Mp3FileReader or another file reader, then your file will eventually reach the end.
You can get notification that playback has finished by subscribing to the PlaybackStopped event. This event will also be able to tell you if playback has stopped due to an error with the soundcard. For example, if your device is a USB headset and you unplug it midway through playing, then you will see one of these errors.
waveOut.PlaybackStopped += OnPlaybackStopped;
You can of course request that playback stops at any time by calling Stop. Note that playback may not actually have stopped when this method exits. You've simply requested that playback stops, and it normally happens very quickly. But only when you get the PlaybackStopped event can you be sure it has completely stopped.
waveOut.Stop();
我在 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);
});
}
我正在尝试 运行 在我的 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 在这里不起作用。它直接跳到 finally 块。
问题是 WaveOut.Play()
returns 马上。直接来自 NAudio documentation(强调我的):
Starting playback
Now we're ready to begin playback, and we can do so by simply calling Play on our output device. It's important to note that this is not a blocking call. It just begins playback. If you want to be notified when playback ends, we'll discuss how to do that shortly.
waveOut.Play();
因此,您的 Task
会立即完成,无需等待剪辑播放。 NAudio 文档继续:
Stopping playback
By default, the output device (WaveOutEvent in our case) will keep playing until we reach the end of the input stream we passed into Init. This is indicated when the IWaveProvider.Read method returns 0. Assuming you passed in an Mp3FileReader or another file reader, then your file will eventually reach the end.
You can get notification that playback has finished by subscribing to the PlaybackStopped event. This event will also be able to tell you if playback has stopped due to an error with the soundcard. For example, if your device is a USB headset and you unplug it midway through playing, then you will see one of these errors.
waveOut.PlaybackStopped += OnPlaybackStopped;
You can of course request that playback stops at any time by calling Stop. Note that playback may not actually have stopped when this method exits. You've simply requested that playback stops, and it normally happens very quickly. But only when you get the PlaybackStopped event can you be sure it has completely stopped.
waveOut.Stop();
我在 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);
});
}