dotnet/wpf · error · InvalidOperationException
SR.Image_LockCountLimit
Error message
SR.Image_LockCountLimit
What it means
TryLock refuses to increment the lock count past UInt32.MaxValue. Every Lock/TryLock call must be balanced by Unlock; an unbalanced (or recursive re-entrant without unlock) locking pattern accumulates locks until the counter saturates, which is a programming bug, so the library throws InvalidOperationException with SR.Image_LockCountLimit.
Solutions
- Balance every Lock/TryLock with exactly one Unlock, ideally in a finally block.
- Wrap lock/unlock in IDisposable (using pattern) so exceptions cannot leak the lock.
- Audit for re-entrant locking in per-frame code paths.
- Reuse a single lock scope per frame instead of nested lock calls.
Example fix
// before
bitmap.Lock();
WritePixels(...);
if (error) return; // unlock lost
bitmap.Unlock();
// after
bitmap.Lock();
try { WritePixels(...); }
finally { bitmap.Unlock(); } Defensive patterns
Strategy: try-catch
Validate before calling
if (bitmap._lockCount unchecked) — not public; instead track your own acquire count and assert it stays small: Debug.Assert(myLockDepth < 100);
Try / catch
try { if (!bitmap.TryLock(Duration.Forever)) return; DoWork(); } finally { bitmap.Unlock(); } Prevention
- Always pair Lock/TryLock with Unlock in finally
- Encapsulate in using/IDisposable wrapper
- Avoid per-frame locking without release; audit hot loops
When it happens
Trigger: Calling TryLock/Lock repeatedly (e.g., in a render loop) without a matching Unlock, roughly 4 billion times, or leaking locks due to early returns in a try block that skips Unlock.
Common situations: Long-running WPF apps that lock WriteableBitmaps per frame and lose unlocks on exception paths; helpers that lock on the caller's behalf without unlocking.
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
- Animation_Invalid_DefaultValue
- ArgumentNullException (buffer/sourceBuffer was IntPtr.Zero)
- ArgumentOutOfRangeException (timeout was Duration.Automatic)
- Cannot remove signature from read-only file.
- Image_EncoderNoColorContext
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5040b90415992fcf.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/WriteableBitmap.cs:243
WritePreamble();
TimeSpan timeoutSpan;
if (timeout == Duration.Automatic)
{
throw new ArgumentOutOfRangeException(nameof(timeout));
}
else if (timeout == Duration.Forever)
{
timeoutSpan = TimeSpan.FromMilliseconds(-1);
}
else
{
timeoutSpan = timeout.TimeSpan;
}
if (_lockCount == UInt32.MaxValue)
{
throw new InvalidOperationException(SR.Image_LockCountLimit);
}
if (_lockCount == 0)
{
// Try to acquire the back buffer by the supplied timeout, if the acquire call times out, return false.
if (!AcquireBackBuffer(timeoutSpan, true))
{
return false;
}
Int32Rect rect = new Int32Rect(0, 0, _pixelWidth, _pixelHeight);
HRESULT.Check(UnsafeNativeMethods.WICBitmap.Lock(
WicSourceHandle,
ref rect,
LockFlags.MIL_LOCK_WRITE,
out _pBackBufferLock
));View on GitHub (pinned to 81131a70a4)