dotnet/wpf · error · ArgumentOutOfRangeException
throw new ArgumentOutOfRangeException(nameof(timeout));
Error message
throw new ArgumentOutOfRangeException(nameof(timeout));
What it means
D3DImage.TryLock(Duration timeout) attempts to acquire the render lock without blocking indefinitely, so a Duration.Automatic timeout is meaningless and rejected: it throws ArgumentOutOfRangeException for parameter 'timeout'. Only finite durations and Duration.Forever are acceptable.
Solutions
- Pass a concrete timeout, e.g. TryLock(TimeSpan.FromMilliseconds(50)) or TryLock(Duration.Forever) for blocking behavior identical to Lock().
- Before calling, check `duration != Duration.Automatic` and substitute a real duration.
- If you need a 'best effort, no wait' lock, use a very small finite duration such as Duration.Zero or TimeSpan.Zero.
Example fix
// before
Duration d = new Duration(); // Automatic
d3dImage.TryLock(d); // ArgumentOutOfRangeException
// after
var d = TimeSpan.FromMilliseconds(50);
if (d3dImage.TryLock(d)) { try { /* render */ } finally { d3dImage.Unlock(); } } Defensive patterns
Strategy: validation
Validate before calling
if (duration == Duration.Automatic)
duration = Duration.Forever; // or a concrete TimeSpan
bool got = d3dImage.TryLock(duration); Try / catch
try { return d3dImage.TryLock(timeout); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "timeout")
{
return d3dImage.TryLock(TimeSpan.FromMilliseconds(50));
} Prevention
- Never reuse Duration values taken from animations for timeouts.
- Use explicit TimeSpan values (or Duration.Forever) for TryLock.
- Avoid default(Duration) — it equals Automatic.
When it happens
Trigger: Calling TryLock(new Duration()) (default Duration == Automatic); passing Duration.Automatic explicitly (e.g. reusing a Duration taken from an animation); constructing a Duration from a TimeSpan that was never set or via a default struct.
Common situations: Copying Duration values from animation timelines (where Automatic is legal) into TryLock; default-initialized Duration fields; timing code that computes a Duration lazily and never assigns it.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- args
- args
- ArgumentOutOfRangeException(authenticationType)
- ArgumentOutOfRangeException
- ArgumentOutOfRangeException(nameof(characterHit))
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f6998b388df74323.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/D3DImage.cs:237
/// </summary>
public void Lock()
{
WritePreamble();
LockImpl(Duration.Forever);
}
/// <summary>
/// Trys to lock the D3DImage but gives up once duration expires. Returns true
/// if the lock was obtained. See Lock for more details.
/// </summary>
public bool TryLock(Duration timeout)
{
WritePreamble();
if (timeout == Duration.Automatic)
{
throw new ArgumentOutOfRangeException(nameof(timeout));
}
return LockImpl(timeout);
}
/// <summary>
/// Unlocks the D3DImage
///
/// Can only be called while locked.
///
/// If you have dirtied the image with AddDirtyRect, Unlocking will trigger us to
/// copy the dirty regions from the back buffer to the front buffer. While this is
/// taking place, Lock will block. To avoid locking indefinitely, use TryLock.
/// </summary>
public void Unlock()
{
WritePreamble();
View on GitHub (pinned to 81131a70a4)