dotnet/wpf · error · ObjectDisposedException
SR.ByteRangeDownloaderDisposed
Error message
SR.ByteRangeDownloaderDisposed
What it means
ObjectDisposedException thrown by ByteRangeDownloader.CheckDisposed when any public operation (GetDownloadedByteRanges, RequestByteRanges, or the Proxy/Credentials/CachePolicy/FileMutex properties) is invoked after the downloader's Dispose path set _disposed to true.
Solutions
- Stop using the instance after Dispose; create a new ByteRangeDownloader if more downloads are needed
- Guard usage with a disposed flag or lock shared between dispose and use
- Fix ownership so only one component disposes the downloader
Example fix
// before downloader.Dispose(); downloader.RequestByteRanges(ranges); // throws // after downloader.Dispose(); downloader = new ByteRangeDownloader(uri, handle, tempFile); downloader.RequestByteRanges(ranges);
Defensive patterns
Strategy: try-catch
Validate before calling
// guard flag maintained by caller
bool usable = downloader != null && !disposed;
if (!usable) throw new InvalidOperationException("Downloader already disposed"); Try / catch
try {
downloader.RequestByteRanges(ranges);
} catch (ObjectDisposedException) {
downloader = new ByteRangeDownloader(uri, handle, tempFile);
downloader.RequestByteRanges(ranges);
} Prevention
- Synchronize Dispose and usage with a lock or disposed flag
- Dispose only when all outstanding requests are complete
- Recreate the downloader instead of reusing a disposed instance
When it happens
Trigger: Calling GetDownloadedByteRanges or RequestByteRanges, or reading/writing Proxy, Credentials, CachePolicy, or FileMutex after downloader.Dispose().
Common situations: Race conditions where one thread disposes the downloader while another still uses it, or continued use in a finally block / cache after disposal.
Related errors
- SR.StorageRootDisposed
- Cannot access Stream object because it was closed or…
- EncryptedPackageEnvelope object was disposed.
- FixedPageReader
- SR.RequestAlreadyStarted
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/1dcc8a47a3737551.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/IO/Packaging/ByteRangeDownloader.cs:390
//------------------------------------------------------
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
/// <summary>
/// Check if the object is disposed
/// </summary>
/// <remarks>this._disposed is not changed by a thread while another thread is calling this function</remarks>
private void CheckDisposed()
{
if (_disposed)
{
throw new ObjectDisposedException(null, SR.ByteRangeDownloaderDisposed);
}
}
/// <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);
View on GitHub (pinned to 81131a70a4)