SoundPlayer在Vista上崩溃
以下代码在Vista计算机上导致间歇性崩溃。
using (SoundPlayer myPlayer = new SoundPlayer(Properties.Resources.BEEPPURE)) myPlayer.Play();
我非常怀疑这是此代码,因为该程序在每次哔哔声中或者哔哔哔之前崩溃。我在我的应用程序域中有所有" ThreadExceptions"," UnhandledExceptions"的顶级陷阱,以及" Application.Run"周围的" try-catch"陷阱,没有一个陷阱可以捕获此崩溃。
有任何想法吗?
编辑:
事件查看器具有以下信息:
Faulting application [xyz].exe, version 4.0.0.0, time stamp 0x48ce5a74, faulting module msvcrt.dll, version 7.0.6001.18000, time stamp 0x4791a727, exception code 0xc0000005, fault offset 0x00009b30, process id 0x%9, application start time 0x%10.
有趣的是," HRESULT 0xc0000005"具有以下消息:
"Reading or writing to an inaccessible memory location." (STATUS_ACCESS_VIOLATION)
解决方案
回答
我们可以使用WinDBG并捕获所有优先机会异常。我相信我们会看到一些有趣的东西。如果是这样,我们可以使用SOS清理堆栈并将其张贴在此处以帮助我们。
或者,我们可以通过启用所有异常的陷阱来使用Visual Studio。转到"调试",然后"异常",并确保我们捕获所有内容。与此同时将调试器切换到混合模式(托管和非托管)。
一旦有了堆栈跟踪,我们就可以确定答案。
进程在Windows上无一例外都不会退出。在里面另外,我们可能想检查机器的事件日志以查看是否有任何显示。
回答
事件查看器显示HRESULT 0xc0000005"读取或者写入不可访问的内存位置。" (STATUS_ACCESS_VIOLATION)
有关更多详细信息,请参见上面的编辑。重复此过程需要一段时间,因此我暂时无法获得WinDBG的新崩溃转储。
回答
解决方案是使用不受此错误困扰的Microsoft.VisualBasic.Devices。由于它仅是Vista,并且事件查看器甚至在记录崩溃时中途都失败了(进程ID 0x **%9 **应该在那里有一个十六进制值),我将责任归咎于Vista中的新声音代码。
顺便说一句,将VS调试器连接到崩溃的进程进行了远程管理,以便首先挂起Visual Studio,然后在杀死无响应的devenv.exe的同时在我的计算机上造成BSOD。精彩的!
回答
这里纯粹是猜测,但是问题可能出在using语句上。代码是这样的(我认为):
using (SoundPlayer myPlayer = new SoundPlayer(BEEPPURE)) { myPlayer.Play(); }
using块有时会在完成播放声音之前在myPlayer上调用Dispose()(但很少,因为声音太短,声音更长,我敢打赌,每次都可以重现错误)。该错误是Windows API(SoundPlayer包装的)试图播放已由.NET处置的缓冲区的结果。
我认为如果我们这样做:
SoundPlayer myPlayer = new SoundPlayer(BEEPPURE); myPlayer.Play();
甚至
(new SoundPlayer(BEEPPURE)).Play();
我们将不会再看到该错误。
回答
实际上,上面的代码(即new SoundPlayer(BEEPPURE))。Play();为我坠毁。
本文说明了原因,并提供了可以完美运行的SoundPlayer替代品:
http://www.codeproject.com/KB/audio-video/soundplayerbug.aspx?msg=2862832#xx2862832xx