beattiet's picture

Audio context fails to create - unhandleable exception

Project:The Open Toolkit library
Version:1.0-2010-10-06
Component:Code
Category:support request
Priority:normal
Assigned:Unassigned
Status:open
Description

We have a client with a computer with "no dedicated sound card" (whatever that means). Our software fails to create an Audio Context with the following exception...

EXCEPTION Unhandled exception: System.TypeInitializationException
The type initializer for 'OpenTK.Audio.AudioContext' threw an exception.
The type initializer for 'OpenTK.Audio.AudioDeviceEnumerator' threw an exception.
at OpenTK.Audio.AudioContext.Finalize()

As best we can figure, it seems to fail in the enumerator, which causes the constructor to fail, which causes a call to Finalize, which causes the enumerator to fail...
We are unable to handle it in the usual way (try/catch) because Microsoft says that exceptions in Finalize methods are unhandleable.

Anyone with similar experience?
Is it possible to put some protection in the AudioContext.Finalize to catch any exceptions?


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Inertia's picture

#1

Not sure I understand the situation where this arises correctly: the user has no longer a sound hardware installed, but still an OpenAL driver? Do you know OS and .Net/Mono version of the user?

beattiet's picture

#2

We only know they are on Windows 7 but not much more yet. So I am guessing a fairly recent .Net version as well. We have deployed the OpenAL-soft library (renamed as OpenAL.DLL) as a wrapper around any existing drivers. My question was really about whether we could add some protection to the Finalize code to cover this situation.
I guess the other question is, is there any way to detect the AudioContext constructor is going to fail *before* calling it to avoid this problem? Most of the calls I can see in the code call the device enumerator and that is where the problem arises.

beattiet's picture

#3

It is easy to reproduce - just rename or hide the openAL.dll and the constructor will throw a DLLNotFoundException. Many people will not see this finalization exception as it can happen after the main form is destroyed but our program is catching all exceptions and this one causes a problem because it occurs in a destructor and so cannot be handled using the normal methods.

The solution is to wrap the "finally" portion of the static AudioDeviceEnumerator constructor in a try..catch loop because some of the code in the block can produce exceptions.

                try
                {
                    // clean up the dummy context
                    Alc.MakeContextCurrent( ContextHandle.Zero );  //can cause exception if no dll present
                    if ( dummy_context != ContextHandle.Zero && dummy_context.Handle != IntPtr.Zero )
                        Alc.DestroyContext( dummy_context );
                    if ( dummy_device != IntPtr.Zero )
                        Alc.CloseDevice( dummy_device );
                }
                catch ( Exception )
                {
                    openal_supported = false;
                }