dotnet/wpf · error · ArgumentException
SR.InvalidEventHandle
Error message
SR.InvalidEventHandle
What it means
ByteRangeDownloader's constructor requires a valid, open SafeFileHandle-backed event handle; it signals this handle when asynchronous download work completes. If the handle is null, invalid, or already closed, it throws ArgumentException keyed by SR.InvalidEventHandle.
Solutions
- Create a fresh valid AutoResetEvent/ManualResetEvent handle (via its SafeWaitHandle) and pass it before any disposal
- Check eventHandle.IsInvalid/IsClosed before constructing
- If the handle was closed, recreate it rather than reusing the stale handle
Example fix
// before
var ev = new AutoResetEvent(false);
ev.Dispose();
new ByteRangeDownloader(uri, ev.SafeWaitHandle, timeout);
// after
using var ev = new AutoResetEvent(false);
if (!ev.SafeWaitHandle.IsInvalid && !ev.SafeWaitHandle.IsClosed)
new ByteRangeDownloader(uri, ev.SafeWaitHandle, timeout); Defensive patterns
Strategy: validation
Validate before calling
bool validHandle = h != null && !h.IsInvalid && !h.IsClosed;
Type guard
static bool IsValidWaitHandle(SafeWaitHandle? h) => h is { IsInvalid: false, IsClosed: false }; Try / catch
try { var d = new ByteRangeDownloader(uri, handle, timeout); } catch (ArgumentException ex) when (ex.ParamName == "eventHandle") { handle = new AutoResetEvent(false).SafeWaitHandle; } Prevention
- Keep the event handle alive for the downloader's lifetime
- Never pass disposed SafeWaitHandles; recreate instead
When it happens
Trigger: Calling the public ByteRangeDownloader constructor with an eventHandle that is null, has IsInvalid==true, or IsClosed==true (e.g. a handle disposed elsewhere or never created via CreateEvent).
Common situations: The event handle was disposed by another thread before the constructor ran, or a failed CreateEvent (returns null/invalid) result is passed through unchecked.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Win32Exception (native Win32 error from DuplicateHandle…
- ArgumentNullException
- Can only countersign parts with Digital Signature…
- Duplicates not allowed - signature part already exists.
- ExtendedProperty is already part of the…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a4f9cdcb81ec2543.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/IO/Packaging/ByteRangeDownloader.cs:411
/// <summary>
/// Constructor for ByteRangeDownloader
/// </summary>
private ByteRangeDownloader(Uri requestedUri, SafeWaitHandle eventHandle)
{
ArgumentNullException.ThrowIfNull(requestedUri);
// Ensure uri is correct scheme (http or https) Do case-sensitive comparison since Uri.Scheme contract is to return in lower case only.
if (!string.Equals(requestedUri.Scheme, Uri.UriSchemeHttp, StringComparison.Ordinal) && !string.Equals(requestedUri.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal))
{
throw new ArgumentException(SR.InvalidScheme, nameof(requestedUri));
}
ArgumentNullException.ThrowIfNull(eventHandle);
if (eventHandle.IsInvalid || eventHandle.IsClosed)
{
throw new ArgumentException(SR.InvalidEventHandle, nameof(eventHandle));
}
_requestedUri = requestedUri;
_eventHandle = eventHandle;
}
/// <summary>
/// Check if it has been errored out from the worker thread and re-throw the exception that was
/// thrown from the worker thread
/// </summary>
/// <remarks>No need to lock in this function since the caller always locks before making this call</remarks>
private void CheckErroredOutCondition()
{
if (_erroredOut)
{
throw new InvalidOperationException(SR.ByteRangeDownloaderErroredOut, _erroredOutException);
}
}View on GitHub (pinned to 81131a70a4)