WinForms 申请表“Shakes”音频播放时
我正在开发一个 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 的解决方案。这仍然有待证明是否是一个令人满意的解决方案,因为会发生交叉主题,即可以在旧的样本仍在播放的同时启动新的样本线程。
随着更多知识的曝光,我们将更新此内容。
I have a C# game program that i'm developing. it uses sound samples and winsock.
when i test run the game most of the audio works fine but from time to time if it is multiple samples being played sequentially the application form shakes a little bit and then goes back to its old position.
how do i go about debugging this or present it to you folks in a manageable manner? i'm sure no one is going to want the whole app code in fear of virus attacks.
please guide me..
EDIT: i have not been able to pin down any code section that produces this result. it just does and i cannot explain it.
EDIT: no the x/y position are not changing. the window like shakes around a few pixels and then goes back to the position were it was before the shake.
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();
}
can you see anything in the above code that would produce this shake?
EDIT: yes the code is being executed within a: this.Invoke(new Action(delegate(){ ....})); could this be it? how do i resolve this?
EDIT:
stream = Properties.Resources.ResourceManager.GetStream("_destroyed");
player = new System.Media.SoundPlayer(stream);
player.PlaySync();
player.Dispose();
stream.Dispose();
if the take out the above code, then it works fine! any ideas?
EDIT: i replaced the line with:
stream = Properties.Resources.ResourceManager.GetStream("_destroyed");
to a different file name but the problem is still there but at least it is not the audio file is corrupt.
EDIT: MSN when someone sends a nudge? it is bit like that but only happens 2 or 3 times.
EDIT: Are you using any 3rd party libraries? - no i am not using any 3rd party libs.
EDIT: it seems no matter what file, the 3rd sample always causes this.
EDIT: happens everywhere i use sound samples. if i play 3 samples, the situation happens.
EDIT: @nobugz: yes think you are right. the problem is holding up the UI thread for too long. as i have tried just using a merged audio file and the problem is there given its original duration.
EDIT: i solved this issue by putting Application.DoEvents();
after each sample play command. no shakes :)
EDIT: the above solution did not really work. as the number of player samples grew the application GUI got stuck again. a solution using QueueUserWorkItem has been employed instead. this still remains to be proven as a satisfactory solution as cross therading occurs i.e. a new thread of samples can be started while an old one is still playing.
will update this as more knowledge comes to light.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 UI 线程上调用 PlaySync 并不是那么好。它会使你的主窗口无响应,因为你的 UI 线程正忙于等待声音结束,它不会像它应该做的那样抽出时间来发送消息。如果花费的时间足够长,Windows 就会介入并用“幽灵”重叠窗口,标题栏中通常会显示“未响应”(如果有的话)。这个幽灵窗口可能与您自己的窗口不太匹配,这可以解释“摇晃”的原因。
使用 Play() 可以解决这个问题。但如果你换了一个新的,排序声音就变得很困难。从线程进行调用可以解决这两个问题。查看 NAudio 以更好地控制声音。
Calling PlaySync on the UI thread isn't so great. It will make your main window unresponsive as your UI thread is busy waiting for the sound to finish, it doesn't get around to pumping messages like it should do. If that takes long enough, Windows steps in and overlaps the window with a "ghost", it usually says "Not Responding" in the title bar (if it has one). This ghost window might not quite match your own window, that could explain the "shaking".
Using Play() instead will solve that problem. But gets you a new one, sequencing sounds becomes difficult. Making the calls from a thread can solve both. Check out NAudio for better control over sound.
复制您的程序。从副本中删除尽可能多的游戏元素。删除模块,删除游戏逻辑,在类之间转移函数以减少抽象(以便您可以删除类),并且通常会破解游戏。
每次执行此操作时,请检查错误是否仍然存在。最初,您将删除程序的较大块,但随着时间的推移,删除量将会减少。
如果您发现某些内容在删除后修复了错误,则有两种可能性:您发现了错误,或者与程序的其余部分存在某种协同作用导致了错误。在后一种情况下,继续删除更多程序。
最终,您将得到一个存在错误的最小程序。将其发布到此处(如果太大,则将其发布到粘贴箱中)。
这是当我遇到根本无法定位的错误时我使用的最后手段之一。
Make a copy of your program. Delete as many game elements from the copy as possible. Remove modules, chop out game logic, shift functions between classes to reduce abstraction (so that you can delete classes), and generally hack up the game.
Each time you do so, check if the bug still exists. Initially you'll be deleting bigger chunks of the program but over time the amount of deletion will reduce.
If you find something which, when deleted, fixes the bug, there are two possibilities: Either you found the bug, or there is some sort of synergy with the rest of the program to cause the bug. In the latter case, continue deleting more of the program.
Eventually, you will end up with a minimal program that has the bug. Post that here (or in a pastebin if it's too big).
This is one of the last-resort strategies I use when I encounter a bug that I am unable to locate at all.