Vista で SoundPlayer がクラッシュする
-
01-07-2019 - |
質問
次のコードは、Vista マシンで断続的なクラッシュを引き起こします。
using (SoundPlayer myPlayer = new SoundPlayer(Properties.Resources.BEEPPURE))
myPlayer.Play();
ビープ音の途中または毎回ビープ音が鳴る直前にプログラムがクラッシュするため、このコードが原因であると強く疑っています。すべてにトップレベルのトラップを用意しています ThreadExceptions
, UnhandledExceptions
私のアプリドメイン内、そして try-catch
その周り Application.Run
, 、どれもこのクラッシュをトラップしません。
何か案は?
編集:
イベント ビューアには次の情報が含まれます。
障害アプリケーション[xyz] .exe、バージョン4.0.0.0、タイムスタンプ0x48ce5a74、フォールトモジュールmsvcrt.dll、バージョン7.0.6001.18000、タイムスタンプ0x4791a727、例外コード0xc00005、断層オフセット0x00009b30、プロセスID 0x% %10。
興味深いことに、 HRESULT 0xc0000005
メッセージがあります:
「アクセスできないメモリの位置を読んだり書いたりします。」 (status_access_violation)
解決
実際には、上記のコード (つまり、new SoundPlayer(BEEPPURE)).Play();私にとってクラッシュしていました。
この記事ではその理由を説明し、問題なく動作する SoundPlayer の代替手段を提供します。
http://www.codeproject.com/KB/audio-video/soundplayerbug.aspx?msg=2862832#xx2862832xx
他のヒント
WinDBG を使用すると、すべての初回例外をトラップできます。きっと面白いものが見つかると思います。その場合は、SOS を使用してスタックをクリーンアップし、ここに投稿して支援してください。
または、すべての例外のトラップを有効にして Visual Studio を使用することもできます。「デバッグ」、「例外」の順に移動し、すべてをトラップしていることを確認します。これは、デバッガーを混合モード (マネージド モードとアンマネージド モード) に切り替えると同時に実行します。
スタック トレースが得られれば、答えを判断できます。
Windows ではプロセスは例外なく終了しません。そこにあります。また、マシンのイベント ログをチェックして、何かが表示されているかどうかを確認することもできます。
イベントビューアーには、HRESULT 0XC0000005「アクセスできないメモリの位置を読み書き」に表示します。 (status_access_violation)
詳細については、上記の私の編集を参照してください。これを再現するには時間がかかるため、しばらくの間 WinDBG の新しいクラッシュ ダンプを取得できません。
解決策は、このバグの影響を受けない Microsoft.VisualBasic.Devices を使用することです。これは Vista のみであり、イベント ビューアはクラッシュのログ記録の途中で失敗することさえあったため (プロセス ID 0x**%9** には代わりに 16 進値が含まれているはずです)、私はその責任を Vista の新しいサウンド コードに指摘します。
ところで、VS デバッガーをクラッシュ プロセスにリモートで接続すると、最初に Visual Studio がハングし、次に応答しない devenv.exe を強制終了するときにマシン上で BSOD が発生しました。素晴らしい!
ここでは純粋な推測ですが、問題は using ステートメントにある可能性があります。あなたのコードは次のようなものです(私はそう思います):
using (SoundPlayer myPlayer = new SoundPlayer(BEEPPURE))
{
myPlayer.Play();
}
using ブロックは、サウンドの再生が完了する前に、myPlayer で Dispose() を呼び出します (ただし、サウンドが非常に短いため、まれに、より長いサウンドを使用すると、毎回エラーを再現できると思います)。このエラーは、(SoundPlayer がラップする) Windows API が .NET によってすでに破棄されたバッファを再生しようとした結果として発生します。
これを行うと次のようになると思います。
SoundPlayer myPlayer = new SoundPlayer(BEEPPURE);
myPlayer.Play();
あるいは
(new SoundPlayer(BEEPPURE)).Play();
エラーは表示されなくなります。