对于我正在研究的游戏,我想把音频放在另一个线程上,这样我就可以将声音排队并让它们立即播放。我在该线程中使用的代码如下所示
private void _checkForThingsToPlay()
{
while (true)
{
if (_song != null)
{
_playSong(_song);
_song = null;
}
while (_effects.Count > 0)
_playSfx(_effects.Dequeue());
Thread.Sleep(100);
}
}
这是异步运行并且运行良好。但是,如果没有呼叫睡眠,它会占用cpu上的整个核心。我的问题是,sleep()是降低CPU使用率的有效方法还是有更好的方法来做到这一点?我的朋友和我觉得这是一个快速的黑客攻击。
答案 0 :(得分:7)
在Thread.Sleep()
循环中使用while(true)
通常是一个坏习惯。看起来你有一个你想要推动音效的队列,你希望“音频线程”在它们被推入队列后立即播放这些效果。这听起来像producer/consumer queue。有多种方法可以在C#中构建这样的队列。您可以使用Monitor.Wait()
和Monitor.Pulse()
,也可以使用AutoResetEvent
对象。
在.NET 4中,您还可以使用BlockingCollection
。
顺便说一句,有一篇非常好的在线介绍threading in C#,介绍了很多常见的线程/同步场景和最佳实践。
答案 1 :(得分:5)
这称为producer-consumer problem,可以轻松解决。如果您使用的是.NET 4,请尝试BlockingCollection
。 MSDN page中有一个很好的示例代码。
请注意示例代码中的这一行:
while (true) Console.WriteLine(bc.Take());
这将实际阻止(没有浪费CPU周期),直到消耗为止。