gpt4 book ai didi

c# - 如何使用System.Media.SoundPlayer异步播放声音文件?

转载 作者:可可西里 更新时间:2023-11-01 08:11:09 33 4
gpt4 key购买 nike

这是一个看似简单的问题:

在 Windows 窗体中异步播放嵌入式 .wav 资源文件的正确方法是什么?

尝试 #1:

var player = new SoundPlayer();
player.Stream = Resources.ResourceManager.GetStream("mySound");
player.Play(); // Note that Play is asynchronous
  • 好:不会阻塞 UI 线程
  • 差:SoundPlayer 和嵌入式资源流不是立即处置。

尝试#2:

using (var audioMemory = Resources.ResourceManager.GetStream("mySound"))
{
using (var player = new SoundPlayer(audioMemory))
{
player.Play();
}
}
  • 好:UI 线程未被阻塞,SoundPlayer 和音频内存流立即被释放。
  • 差:比赛条件! Play() 是异步的,如果音频内存在 Play 完成之前被处理掉……砰!抛出运行时异常。

尝试 #3:

using (var audioMemory = Resources.ResourceManager.GetStream("mySound"))
{
using (var player = new SoundPlayer(audioMemory))
{
player.PlaySync();
}
}
  • 好:立即处理播放器和音频流。
  • 差:PlaySync 阻塞了 UI 线程

尝试 #4:

ThreadPool.QueueUserWorkItem(ignoredState =>
{
using (var audioMemory = Resources.ResourceManager.GetStream("mySound"))
{
using (var player = new SoundPlayer(audioMemory))
{
player.PlaySync();
}
}
});
  • 好:UI 不会卡住,播放器和内存流会立即处理掉。
  • 坏:因为这经常触发,我们可能会用完线程池线程!参见拉里奥斯特曼的 what's wrong with this code part 26 .

SoundPlayer 似乎应该有一个 PlayAsyncCompleted 事件。不幸的是,不存在这样的事件。我错过了什么吗?在 Windows 窗体中异步播放 .wav 嵌入式资源的正确方法是什么?

最佳答案

我没有足够的声誉来发表评论,所以我只是回答。

如果您对播放声音的要求“看似简单”(您只想在单个 winform 用户做某事时偶尔播放声音),那么我会使用上面的尝试 #4。

Larry Osterman 的“此代码第 26 部分有什么问题”让他的“系统”在每次击键时分拆出一个新的线程池线程(以播放声音)。他指出,在输入大约 15 秒后,默认的 500 线程池大小就会饱和,但这也适用于使用异步 RPC 的客户端/服务器应用程序,该应用程序也使用了线程池。确实不是一个“看似简单”的应用程序。

如果您尝试每秒(或更快)将声音字节排队 10 秒或 100 秒,那么它真的不是一个“简单的应用程序”,排队的线程/优先级子系统可能是有序的。

关于c# - 如何使用System.Media.SoundPlayer异步播放声音文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1161229/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com