dotnet/wpf · error · InvalidOperationException
SR.GenerationInProgress
Error message
SR.GenerationInProgress
What it means
IItemContainerGenerator.StartAt begins a generation pass by creating a Generator; only one generation may be active at a time. Calling StartAt while an existing generator is still active (_generator != null, i.e. its IDisposable not disposed) throws InvalidOperationException(SR.GenerationInProgress).
Solutions
- Dispose the IDisposable from each StartAt before calling StartAt again (use a using block)
- Ensure exceptions inside generation loops don't leak undisposed generators
- Avoid calling generator APIs from multiple threads; generation is single-pass, UI-thread work
Example fix
// before
var g1 = gen.StartAt(pos, dir, true);
var g2 = gen.StartAt(pos, dir, true); // throws
// after
using (gen.StartAt(pos, dir, true))
{
while (gen.GenerateNext() is DependencyObject c) { gen.Remove(c); }
} Defensive patterns
Strategy: validation
Validate before calling
// track your own active generation token if (_activeGeneration == null) _activeGeneration = iicg.StartAt(pos, dir, allow);
Try / catch
try { using (iicg.StartAt(pos, dir, allow)) { /* generate */ } } catch (InvalidOperationException ex) { /* a generation pass is still active */ } Prevention
- Always dispose the IDisposable from StartAt (use using)
- Handle exceptions so Dispose still runs
- Do not run generation concurrently on the same generator
When it happens
Trigger: Calling StartAt (or GenerateNext within it) without disposing the IDisposable returned by a previous StartAt; nested generation loops over the same generator.
Common situations: Custom virtualizing panels iterating items with a using-scope bug (early return or exception skipping Dispose); generating containers on two threads against the same generator.
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
- SR.CannotFindRemovedItem
- SR.CannotRecyleHeterogeneousTypes
- SR.Format(SR.CannotRemoveUnrealizedItems, index, count)
- SR.Format(SR.CollectionAddEventMissingItem, item)
- SR.Format(SR.RemoveRequiresOffsetZero, position.Index…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a10d655aba8c906a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemContainerGenerator.cs:207
/// Error, as appropriate.
/// </remarks>
IDisposable IItemContainerGenerator.StartAt(GeneratorPosition position, GeneratorDirection direction)
{
return ((IItemContainerGenerator)this).StartAt(position, direction, false);
}
/// <summary> Begin generating at the given position and direction </summary>
/// <remarks>
/// This method must be called before calling GenerateNext. It returns an
/// IDisposable object that tracks the lifetime of the generation loop.
/// This method sets the generator's status to GeneratingContent; when
/// the IDisposable is disposed, the status changes to ContentReady or
/// Error, as appropriate.
/// </remarks>
IDisposable IItemContainerGenerator.StartAt(GeneratorPosition position, GeneratorDirection direction, bool allowStartAtRealizedItem)
{
if (_generator != null)
throw new InvalidOperationException(SR.GenerationInProgress);
_generator = new Generator(this, position, direction, allowStartAtRealizedItem);
return _generator;
}
public IDisposable GenerateBatches()
{
if (_isGeneratingBatches)
throw new InvalidOperationException(SR.GenerationInProgress);
return new BatchGenerator(this);
}
DependencyObject IItemContainerGenerator.GenerateNext()
{
bool isNewlyRealized;
if (_generator == null)
throw new InvalidOperationException(SR.GenerationNotInProgress);View on GitHub (pinned to 81131a70a4)