How do you terminate SoundEffect due to crashes in Windows XNA games when they are closed?

I am creating a windows game in xna using Visual C # Express. There are six SoundEffect objects in the game that regularly call Play () methods. The problem is that sometimes when the game closes, it crashes. This seems to happen when the window closes during audio playback. This is the message that appears in Visual C #:

AccessViolationException not handled

Attempted to read or write protected memory. This often indicates that another memory is corrupted.

There is no source in Visual Studio that can be debugged, and when the "get general help for this exception" button is clicked, a blank page will appear.

The code used is very similar to the MSDN example. This seems like a problem that exists somewhere in the base structure somewhere, and not on my code. But of course I don’t know for sure. This has happened many times.

http://msdn.microsoft.com/en-us/library/bb195053.aspx

Details below are for details:

System.AccessViolationException was unhandled Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Source=Microsoft.Xna.Framework StackTrace: at Microsoft.Xna.Framework.Audio.AudioCallbackDispatcher.IsEventRegistered(EventType type) at Microsoft.Xna.Framework.Audio.AudioCallbackDispatcher.UnregisterEvent(EventType type) at Microsoft.Xna.Framework.Audio.KernelMicrophone.ShutdownCaptureEngine() at Microsoft.Xna.Framework.Audio.MicrophoneUnsafeNativeMethods.ShutdownCaptureEngine() at Microsoft.Xna.Framework.Audio.AudioRendererShutdownHandler.AppExitingEventHandler(Object sender, EventArgs args) InnerException: 

(I also have music playing through MediaPlayer, but I don't think this is connected.)

EDIT: It seems I found something that works, but it's kind of hacky and really should not be necessary. I am still open to more elegant solutions.

Call this line in Game1.UnloadContent (). He will be sure (if your sound effects are less than 3 seconds) that the sound does not play when the program really closes.

 System.Threading.Thread.Sleep(3000); 
+4
source share
4 answers

Make the SoundEffect object a member of the class and call the SoundEffect Dispose () method to deconstruct the class:

 class MyClass { ~MyClass() { effect.Dispose(); } SoundEffect effect; } 

This should allow the SoundEffect to clear itself when the game is closed. You can read about objects that can be disposable here: http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

+2
source

Can you force MyClass to implement IDisposable and get rid of SoundEffect in this method?

+1
source

I think it’s pretty confident to say that this is a mistake within the framework. Since this is in the audio code, it is possible that the infrastructure is not processing something that it receives from the driver correctly. It’s hard to say for sure.

Suffice it to say that an AccessViolationException that goes out of scope is not "normal." This is almost certainly not your fault .

The IsEventRegistered function in which the exception occurs is an unsafe function. Thus, it is likely that the function does exactly what the exception says: it accesses an invalid memory address.

The exception comes from the audio capture completion code (microphone), so what do you do with the microphone in the code? You could experiment using / not using a microphone and see what happens.

Also: does this happen when you launch the application without a debugger? (CTRL + F5)

As for fixing the problem: Your solution is not a bad job.

If you cannot afford to wait three seconds and you want your hands to be dirty, and write a very dubious (semi-dangerous, not necessarily forward-compatible) code: you can use reflection to access the private properties of the audio system. Find the list of SoundEffectInstance objects that are created internally when you call SoundEffect.Play , and then stop these instances before shutting down.

Or you could do the same without calling Play , but instead calling CreateInstance and controlling the fire and swell sound effects yourself. The disadvantage is that this requires a lot of code to be written!

+1
source

I had the same problem and I made null for my sound collections in class finalizer (destructor). It works for me.

 public class Audio { private ContentManager content; public List<SoundEffectInstance> SoundInstance { get; private set; } public AudioEmitter Emitter { get; set; } public AudioListener Listener { get; set; } public List<SoundEffect> Sound { get; set; } public Audio(ContentManager content) { this.content = content; Emitter = new AudioEmitter(); Listener = new AudioListener(); Sound = new List<SoundEffect>(); SoundInstance = new List<SoundEffectInstance>(); } //set to null your sound instances and effects :D ~Audio() { Sound = null; SoundInstance = null; } ... 
0
source

Source: https://habr.com/ru/post/1341182/


All Articles