AvaloniaUI/Avalonia · error · InvalidOperationException

This resource is disposed

Error message

This resource is disposed

What it means

CompositorRefCountableResource tracks a per-compositor reference count starting at 1; both AddRef and Release throw InvalidOperationException('This resource is disposed') if RefCount is already <= 0, i.e. the resource was fully released and scheduled for disposal on the next batch.

Source

Thrown at src/Avalonia.Base/Rendering/Composition/Drawing/CompositorResourceHelpers.cs:22

using Avalonia.Media;
using Avalonia.Rendering.Composition.Server;
using Avalonia.Utilities;

namespace Avalonia.Rendering.Composition.Drawing;

internal class CompositorRefCountableResource<T> where T : SimpleServerObject
{
    public T Value { get; private set; }
    public int RefCount { get; private set; }

    public CompositorRefCountableResource(T value)
    {
        Value = value;
        RefCount = 1;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    static void ThrowInvalidOperation() => throw new InvalidOperationException("This resource is disposed");
    
    public void AddRef()
    {
        if (RefCount <= 0)
            ThrowInvalidOperation();
        RefCount++;
    }

    public bool Release(Compositor c)
    {
        if (RefCount <= 0)
            ThrowInvalidOperation();
        RefCount--;
        if (RefCount == 0)
        {
            c.DisposeOnNextBatch(Value);
            return true;
        }

View on GitHub (pinned to 11c5427268)

Solutions

  1. Ensure every AddRef has a matching Release; audit ref-count symmetry in your ICompositionRenderResource implementation.
  2. Do not touch a resource after it has been released to zero; recreate it via CreateOrAddRef if needed.
  3. Drive add/ref only through CreateOrAddRef / Release helpers so the count stays consistent.

Example fix

// before
handle.Release(compositor);
handle.Release(compositor); // RefCount already 0 -> throws

// after
if (handle.Release(compositor))
    handle = null; // mark released, never touch again
Defensive patterns

Strategy: validation

Validate before calling

// Avoid double release: stop touching the handle once it reports fully released.
if (!handle.Release(compositor)) return; // still referenced
handle = null; // fully released; do not AddRef/Release again

Try / catch

try { handle.AddRef(); }
catch (InvalidOperationException ex) when (ex.Message == "This resource is disposed")
{ /* resource gone; recreate via CreateOrAddRef */ }

Prevention

When it happens

Trigger: Calling AddRef or Release on a CompositorRefCountableResource after its ref count already hit zero (double-release, or add-ref after release).

Common situations: Unbalanced AddRef/Release pairs in a custom ICompositionRenderResource, double-disposing a shared brush/pen/geometry resource, or releasing a resource on one path while another path still add-refs it after teardown.

Related errors


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