AvaloniaUI/Avalonia · error · ObjectDisposedException

CompositionImportedGpuImage

Error message

CompositionImportedGpuImage

What it means

Thrown as ObjectDisposedException (nameof CompositionImportedGpuImage) by the Image property when the imported GPU image is null — which happens after Dispose() nulls it, or if Import() was never successful. The property is the accessor for the platform handle; once disposed it is unusable.

Source

Thrown at src/Avalonia.Base/Rendering/Composition/CompositionInterop.cs:124

        IExternalObjectsRenderInterfaceContextFeature feature,
        Func<IPlatformRenderInterfaceImportedImage> importer, IPlatformHandle? handle): base(compositor, context, feature, handle)
    {
        _importer = importer;
    }

    protected override void Import()
    {
        using (Compositor.Server.RenderInterface.EnsureCurrent())
        {
            // The original context was lost and the new one might have different capabilities
            if (Context != Compositor.Server.RenderInterface.Value)
                throw new PlatformGraphicsContextLostException();
            _image = _importer();
        }
    }

    public IPlatformRenderInterfaceImportedImage Image =>
        _image ?? throw new ObjectDisposedException(nameof(CompositionImportedGpuImage));

    public bool IsUsable => _image != null && Compositor.Server.RenderInterface.Value == Context;

    public override void Dispose()
    {
        _image?.Dispose();
        _image = null!;
    }
}

class CompositionImportedGpuSemaphore : CompositionGpuImportedObjectBase, ICompositionImportedGpuSemaphore
{
    private readonly IPlatformHandle _handle;
    private IPlatformRenderInterfaceImportedSemaphore? _semaphore;

    public CompositionImportedGpuSemaphore(IPlatformHandle handle,
        Compositor compositor, IPlatformRenderInterfaceContext context,
        IExternalObjectsRenderInterfaceContextFeature feature) : base(compositor, context, feature, handle)

View on GitHub (pinned to 11c5427268)

Solutions

  1. Check IsUsable before reading Image, and re-import if false.
  2. Do not access Image after Dispose(); drop the reference.
  3. Handle PlatformGraphicsContextLostException during import and recreate the resource on the new context.

Example fix

// before
var img = importedGpuImage.Image; // throws after dispose / context loss
// after
if (!importedGpuImage.IsUsable) importedGpuImage = Reimport(compositor);
var img = importedGpuImage.Image;
Defensive patterns

Strategy: validation

Validate before calling

if (!importedGpuImage.IsUsable) importedGpuImage = Reimport(compositor);
var img = importedGpuImage.Image;

Type guard

static bool IsUsable(CompositionImportedGpuImage i) => i.IsUsable;

Try / catch

try { use(importedGpuImage.Image); }
catch (ObjectDisposedException) { importedGpuImage = Reimport(compositor); use(importedGpuImage.Image); }

Prevention

When it happens

Trigger: Accessing importedGpuImage.Image after calling Dispose(), or after a failed Import (e.g. context lost). IsUsable should be checked first: it returns true only when _image is non-null and the render interface context matches.

Common situations: Holding a reference to an imported image across a device-loss/context-reset; accessing Image after the compositor disposed the object; racing disposal with a render read.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/c0f03238c3acd112. Report an issue: GitHub.