Bug 1345 - Exception after sound plays
Summary: Exception after sound plays
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 4.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Sebastien Pouliot
URL:
Depends on:
Blocks:
 
Reported: 2011-10-07 12:28 UTC by Dean Cleaver
Modified: 2011-10-07 17:08 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Sample project that has the issue (285.63 KB, application/x-zip-compressed)
2011-10-07 12:28 UTC, Dean Cleaver
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Dean Cleaver 2011-10-07 12:28:30 UTC
Created attachment 641 [details]
Sample project that has the issue

I’m getting this exception reported to me:
 
System.ObjectDisposedException: The object was used after being disposed.
  at MonoTouch.AVFoundation.InternalAVAudioPlayerDelegate.FinishedPlaying (MonoTouch.AVFoundation.AVAudioPlayer player, Boolean flag) [0x00000] in <filename unknown>:0 
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00000] in <filename unknown>:0 
  at KleverLogic.FlashValet.iPhone.Valet.Application.Main (System.String[] args) [0x000ed] in /xsl-home/kleverlogic/FlashValet20110906/Mobile/iPhone/Valet/Main.cs:62 
 
No – only lines of code that are mine is the “Main” function in the Application.
 
I’ve searched the entire solution for “FinishedPlaying” and every reference to that event has error handling, and specifically handles ObjectDisposedException. For example:
 
private static void HandlePlayerhandleFinishedPlaying (object sender, AVStatusEventArgs e)
{
                try
                {
                                if (player != null)
                                                player.Dispose();
 
                                player = null;
                }
                catch (ObjectDisposedException)
                {
                                player = null;
                }
                catch (Exception ex)
                {
                                AppDelegate.CurrentAppDelegate.SendError(ex);
                }
}
 
How is this possible? There’s only 2 effectively identical functions in my code. The other one checks a static Boolean, and if set calls Play() again – but has the same ObjectDisposedException trap, yet somehow I am still getting error reports back from the SendError function.
 
Looks to me like the exception is actually something in the MonoTouch.AVFoundation.InternalAVAudioPlayerDelegate.FinishedPlaying (MonoTouch.AVFoundation.AVAudioPlayer player, Boolean flag) function, and not in my code?
 
This is all new with MonoTouch 4.2 – this exact code (actually, without the ObjectDisposedExceptions) has been working perfectly for a while now on 4.0.6.
Comment 1 Sebastien Pouliot 2011-10-07 13:26:39 UTC
I can duplicate with the latest MonoTouch. Will investigate. Thanks for providing the test case.
Comment 2 Sebastien Pouliot 2011-10-07 14:07:47 UTC
The exception comes from new code added in
https://github.com/mono/maccore/commit/291762e96348346a323470096260a7b0e9a9d2ac

However if you do not have the source code debugging enabled you won't see the message* that would have proven useful. 

Miguel can confirm but I believe it's too early, in the finish event, to dispose the player safely. So the right fix is to remove the Dispose call from your HandlePlayerhandleFinishedPlaying method.

* not (yet) sure why but MonoDevelop shows me the default ObjectDisposedException message. Keeping bug open (at NEEDINFO) until I find out why.
Comment 3 Sebastien Pouliot 2011-10-07 14:13:10 UTC
So the right .ctor to use, to provide a message, is:

public ObjectDisposedException (string objectName, string message) : base (message)

because the single-string .ctor does:

public ObjectDisposedException (string objectName) : base (Locale.GetText ("The object was used after being disposed."))

I'll fix this for future releases.
Comment 4 Sebastien Pouliot 2011-10-07 14:53:25 UTC
Fixed (message) in e8fa8dcafe9c51fe7a2835a06763626aee12c557 (master) and in ios5 branch.
Comment 5 Miguel de Icaza [MSFT] 2011-10-07 17:08:19 UTC
The problem is that Dispose()ing the object on a callback destroys the object that you are returning to.

The best solution is to do something like:

foo.BeginInvokeOnMainThread (delegate { Dispose (); })

To ensure that this gets queued on the next iteration through the main loop.