音频播放时WinForms应用程序表单“震动”

时间:2010-03-24 19:05:37

标签: c# winforms shake

我正在开发一个C#游戏程序。它使用声音样本和winsock。

当我测试运行游戏时,大部分音频工作正常,但如果是连续播放的多个样本,应用程序表格会稍微摇动,然后回到原来的位置。

我如何调试这个或以可管理的方式呈现给你们?我确信没有人会因为害怕病毒攻击而想要整个应用程序代码。

请指导我..

编辑:我无法确定产生此结果的任何代码部分。它只是做了,我无法解释它。

编辑:没有x / y位置没有变化。窗口像是在几个像素周围摇晃,然后回到摇晃之前的位置。

if (audio)
{
    Stream stream;
    SoundPlayer player;

    stream = Properties.Resources.ResourceManager.GetStream("_home");
    player = new System.Media.SoundPlayer(stream);
    player.PlaySync();
    player.Dispose();

    string ShipID = fireResult.DestroyedShipType.ToString();
    stream = Properties.Resources.ResourceManager.GetStream("_" + ShipID);
    player = new System.Media.SoundPlayer(stream);
    player.PlaySync();
    player.Dispose();

    stream = Properties.Resources.ResourceManager.GetStream("_destroyed");
    player = new System.Media.SoundPlayer(stream);
    player.PlaySync();
    player.Dispose();
}
你可以在上面的代码中看到任何产生这种震动的内容吗?

编辑:是的,代码正在a:this.Invoke中执行(new Action(delegate(){....}));这可能吗?我该如何解决这个问题?

编辑:

           stream = Properties.Resources.ResourceManager.GetStream("_destroyed");
           player = new System.Media.SoundPlayer(stream);
           player.PlaySync();
           player.Dispose();
           stream.Dispose();

如果拿出上面的代码,那就行了!任何想法?

编辑:我用以下代码替换了

stream = Properties.Resources.ResourceManager.GetStream("_destroyed");

到一个不同的文件名,但问题仍然存在,但至少它不是音频文件已损坏。

编辑:当有人发送推文时MSN?它有点像,但只发生2或3次。

编辑:您使用的是第三方图书馆吗? - 不,我没有使用任何第三方库。

编辑:似乎无论什么文件,第三个样本总是会导致这个。

编辑:在我使用声音样本的任何地方都会发生。如果我播放3个样本,情况会发生。

编辑:@nobugz:是的,你认为你是对的。问题是持续时间过长的UI线程。因为我已经尝试过使用合并的音频文件,问题就在于它的原始持续时间。

编辑:我通过在每个示例播放命令后放置Application.DoEvents();来解决此问题。没有动摇:)

编辑:上述解决方案并没有真正起作用。随着播放器样本数量的增加,应用程序GUI再次陷入困境。已采用使用QueueUserWorkItem的解决方案。这仍然有待证明是一种令人满意的解决方案,因为交叉匹配发生,即一个新的样本线程可以在旧的样本仍在播放时启动。

随着更多知识的出现,

将更新此内容。

2 个答案:

答案 0 :(得分:4)

在UI线程上调用PlaySync并不是那么好。当您的UI线程忙于等待声音完成时,它会使您的主窗口无响应,它不会像它应该那样抽取消息。如果这需要足够长的时间,Windows会进入并重叠窗口并显示“ghost”,它通常会在标题栏中显示“Not Responding”(如果有的话)。这个幽灵窗口可能与你自己的窗口不太匹配,这可以解释“摇晃”。

使用Play()代替将解决该问题。但是给你一个新的,测序声音变得困难。从线程进行调用可以解决这两个问题。查看NAudio以更好地控制声音。

答案 1 :(得分:3)

制作您的计划副本。从副本中删除尽可能多的游戏元素。删除模块,删除游戏逻辑,在类之间移动函数以减少抽象(以便您可以删除类),并且通常会破坏游戏。

每次执行此操作时,请检查错误是否仍然存在。最初你将删除更大的程序块,但随着时间的推移,删除量将减少。

如果你找到一些东西,当删除时修复了这个bug,有两种可能:你找到了这个bug,或者与程序的其余部分有某种协同作用来导致bug。在后一种情况下,继续删除更多的程序。

最终,您将得到一个有bug的最小程序。发布在这里(或者如果它太大则在pastebin中)。

这是我遇到一个我无法找到的错误时使用的最后策略之一。