dotnet/wpf · error · ObjectDisposedException

SR.TextLineHasBeenDisposed

Error message

SR.TextLineHasBeenDisposed

What it means

FullTextLine.Draw throws ObjectDisposedException (SR.TextLineHasBeenDisposed) when drawing a TextLine whose unmanaged resources have already been released. Disposal happens via Dispose() or when the formatter invalidates the line (e.g. ClearLayoutThrow / Dispose on the TextFormatter or re-formatting).

Solutions

  1. Draw the line inside the same scope in which it was formatted, before Dispose.
  2. Do not wrap the TextFormatter in a using block if lines drawn later must remain valid.
  3. Cache the rendered output (DrawingContext/DrawingVisual) instead of the live TextLine.
  4. Re-format the line with TextFormatter.FormatLine if it has been disposed.

Example fix

// before
TextLine line;
using (var tf = TextFormatter.Create())
{
    line = tf.FormatLine(...);
}
line.Draw(dc, origin, inversion); // ObjectDisposedException
// after
using (var tf = TextFormatter.Create())
{
    var line = tf.FormatLine(...);
    line.Draw(dc, origin, inversion);
}
Defensive patterns

Strategy: validation

Validate before calling

void SafeDraw(TextLine line, DrawingContext dc, Point o, InvertAxes a)
{ if (line == null) throw new ArgumentNullException(nameof(line)); line.Draw(dc, o, a); } // call before any Dispose scope closes

Try / catch

try { line.Draw(dc, origin, inversion); }
catch (ObjectDisposedException)
{
    line = formatter.FormatLine(source, ...); // re-create
    line.Draw(dc, origin, inversion);
}

Prevention

When it happens

Trigger: Calling line.Draw(drawingContext, origin, inversion) after line.Dispose(), after TextFormatterImp was disposed (e.g. using-block around the formatter closed), or after caching a line across layout passes and the formatter disposed it.

Common situations: Drawing cached TextLine objects in a later render pass after the formatting scope closed; storing lines in a view-model and drawing them after Dispose was called on cleanup; using 'using' around TextFormatter then drawing lines afterwards.

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 dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/142e123643096f01. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/FullTextLine.cs:539


            /// <summary>
            /// Draw line
            /// </summary>
            /// <param name="drawingContext">drawing context</param>
            /// <param name="origin">drawing origin</param>
            /// <param name="inversion">indicate the inversion of the drawing surface</param>
            public override void Draw(
                DrawingContext      drawingContext,
                Point               origin,
                InvertAxes          inversion
                )
            {
                ArgumentNullException.ThrowIfNull(drawingContext);

                if ((_statusFlags & StatusFlags.IsDisposed) != 0)
                {
                    throw new ObjectDisposedException(SR.TextLineHasBeenDisposed);
                }

                MatrixTransform antiInversion = TextFormatterImp.CreateAntiInversionTransform(
                    inversion,
                    _metrics._formatter.IdealToReal(_paragraphWidth, PixelsPerDip),
                    _metrics._formatter.IdealToReal(_metrics._height, PixelsPerDip)
                    );

                if (antiInversion == null)
                {
                    DrawTextLine(drawingContext, origin, null);
                }
                else
                {
                    // Apply anti-inversion transform to correct the visual
                    drawingContext.PushTransform(antiInversion);
                    try
                    {

View on GitHub (pinned to 81131a70a4)