stride3d/stride · error · ObjectDisposedException

this

Error message

this

What it means

SoundBase.CheckNotDisposed throws ObjectDisposedException with the literal name "this" once the sound asset (SoundBase) has been disposed. It guards internal operations (e.g. querying Channels or creating instances) against use of a disposed sound. The cryptic objectName "this" is a library quirk; the semantic is 'the sound object was disposed'.

Solutions

  1. Stop using the sound after Dispose; guard call sites with IsDisposed checks.
  2. Fix object lifetimes so the sound outlives all code that can create instances from it.
  3. In game-shutdown paths, stop audio system updates before disposing audio assets.

Example fix

// before
var instance = sound.CreateInstance();
// after
if (!sound.IsDisposed)
{
    var instance = sound.CreateInstance();
}
else
{
    logger.Warn("Attempted to use disposed sound");
}
Defensive patterns

Strategy: type-guard

Validate before calling

public static bool CanUseSound(SoundBase sound) => sound != null && !sound.IsDisposed;

Type guard

public static bool IsUsable(SoundBase? sound) => sound is { IsDisposed: false };

Try / catch

try
{
    var instance = sound.CreateInstance();
}
catch (ObjectDisposedException)
{
    logger.Warn("Sound already disposed; skipping instance creation.");
}

Prevention

When it happens

Trigger: Calling instance-creating or property APIs (e.g. CreateInstance, Channel-related access) on a SoundInstance's Sound after sound.Dispose() was called, e.g. during scene teardown order issues.

Common situations: Disposing a SoundInstance or audio asset while other code still references the parent sound and tries to spawn new instances; game shutdown racing with gameplay code still requesting sounds.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/1e560ac6dbb04d60. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Audio/SoundBase.cs:93

        internal void Attach(AudioEngine engine)
        {
            AttachEngine(engine);

            Name = "Sound Effect " + Interlocked.Add(ref soundEffectCreationCount, 1);

            // register the sound to the AudioEngine so that it will be properly freed if AudioEngine is disposed before this.
            AudioEngine.RegisterSound(this);
        }

        public int GetCountChannels()
        {
            return Channels;
        }

        internal void CheckNotDisposed()
        {
            if (IsDisposed)
                throw new ObjectDisposedException("this");
        }

        /// <summary>
        /// Stop all registered instances of the <see cref="SoundBase"/>.
        /// </summary>
        internal void StopAllInstances()
        {
            foreach (var instance in Instances)
                instance.Stop();
        }

        /// <summary>
        /// Stop all registered instances different from the provided main instance
        /// </summary>
        /// <param name="mainInstance">The main instance of the sound effect</param>
        internal void StopConcurrentInstances(SoundInstance mainInstance)
        {
            foreach (var instance in Instances)

View on GitHub (pinned to 96fad776d2)