为了给出一些背景知识,我正在开发一个开源替代桌面Spotify客户端,其核心是可访问性。你还会在这里看到一些NAudio。
一旦播放开始,我就会注意到相当强烈的CPU使用率。即使暂停,CPU也很高。
我运行了Visual Studio的内置分析器,试图揭示可能发生的任何资源生长。我怀疑,问题出在我的播放管理器的流媒体循环中。
探查器标记为样本丰富度最高的代码如下:
const int secondsToBuffer = 3;
private void GetStreaming(object state)
{
this.fullyDownloaded = false;
// secondsToBuffer is an integer to represent how many seconds we should buffer up at once to prevent choppy playback on slow connections
try
{
do
{
if (bufferedWaveProvider == null)
{
this.bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat(44100, 2));
this.bufferedWaveProvider.BufferDuration = TimeSpan.FromSeconds(20); // allow us to get well ahead of ourselves
Logger.WriteDebug("Creating buffered wave provider");
this.gatekeeper.MinimumSampleSize = bufferedWaveProvider.WaveFormat.AverageBytesPerSecond * secondsToBuffer;
}
// this bit in particular seems to be the hot point
if (bufferedWaveProvider != null && bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes < bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 4)
{
Logger.WriteDebug("Buffer getting full, taking a break");
Thread.Sleep(500);
}
// do we have at least double the buffered sample's size in free space, just in case
else if (bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes > bufferedWaveProvider.WaveFormat.AverageBytesPerSecond * (secondsToBuffer * 2))
{
var sample = gatekeeper.Read();
if (sample != null)
{
bufferedWaveProvider.AddSamples(sample, 0, sample.Length);
}
}
} while (playbackState != StreamingPlaybackState.Stopped);
Logger.WriteDebug("Playback stopped");
}
finally
{
// no post-processing work here, right?
}
}
NAudio样本是我用这种方法处理流媒体的方式的灵感来源。要查找完整文件的源代码,您可以在此处查看:http://blindspot.codeplex.com/SourceControl/latest#Blindspot.Playback/PlaybackManager.cs
我是分析的新手,而且我也不是年度流媒体专家(两者都可能很明显)。
有什么办法可以让这个循环不那么耗费资源。会增加缓冲区满的if块中的睡眠量吗?或者我在这里咆哮错误的树。它似乎会,但我认为半秒就足够了。
感激不尽的任何帮助。
答案 0 :(得分:0)
基本上,您已经创建了一个无限循环,直到缓冲区变满为止。您标有
的部分// this bit in particular seems to be the hot point
可能看起来像if语句中的计算只是一遍又一遍地重复;可以将它们中的任何一个移到循环之外吗?
我在while语句之前放了一个Thread.Sleep(50)来防止颠簸,看看是否有所不同(我怀疑它会有所不同)。