C# Bitmap实例化遇System.ArgumentException参数无效问题求助
Hey Austin, let's break down what's causing that ArgumentException and fix your image optimization code.
What's Going Wrong
First, the immediate cause of your "Parameter is not valid" error:
When you open the file with File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite), the file gets locked by your process. Then you try to create a Bitmap using fileStream.Name (which is just the file path)—this attempts to open the same file again, but since it's already in use by your open stream, the system throws this generic argument error (the underlying issue is a file lock conflict).
You also have a few other missteps in your code:
- You're trying to reuse the same stream for both reading the original image and writing the optimized one, without resetting the stream position (which would cause write failures anyway).
- The
Console.ReadLine()calls inside the parallel loop will block all threads until you manually input something—definitely not ideal for batch processing. - Parallel file I/O can lead to race conditions if not handled carefully, even with
FileSharesettings.
Fixed Code
Here's a revised version that addresses all these issues:
string[] imageFiles = Directory.GetFiles(GetSourceDirectory()); Parallel.ForEach(imageFiles, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, (file) => { try { // Load the original image without holding the file lock longer than needed Bitmap originalBitmap; using (var readStream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read)) { originalBitmap = new Bitmap(readStream); } // Quantize the image using (originalBitmap) using (var quantizedBitmap = quantizer.QuantizeImage(originalBitmap, 1, 1)) { // Overwrite the original file with the optimized image using (var writeStream = File.Open(file, FileMode.Create, FileAccess.Write, FileShare.None)) { quantizedBitmap.Save(writeStream, ImageFormat.Png); } // Upload to blob storage (simplified to use the saved file directly) var blob = container.GetBlockBlobReference(Path.GetFileName(file)); blob.UploadFromFileAsync(file).Wait(); } Console.WriteLine($"Successfully processed: {file}"); } catch (Exception ex) { Console.WriteLine($"Failed to process {file}: {ex.Message}"); } });
Key Improvements
- Separate Read/Write Streams: We first open the file in read-only mode to load the bitmap, then immediately close that stream (releasing the file lock) before opening it again for writing. This eliminates the lock conflict that caused your original error.
- Proper Resource Disposal: All disposable objects (bitmaps, streams) are wrapped in
usingstatements to ensure resources are cleaned up correctly. - Controlled Parallelism: Added
MaxDegreeOfParallelismto avoid overwhelming your disk with too many concurrent file operations. - Simplified Blob Upload: Using
UploadFromFileAsyncinstead of reusing the write stream avoids issues with stream position and closed streams. - Batch-Friendly Error Handling: A try/catch around each file ensures one failed image doesn't crash the entire batch.
Additional Checks
If you still run into issues:
- Verify all files in the folder are valid image files (corrupted images can also throw "Parameter is not valid" when creating a
Bitmap). - Add a filter for image extensions (e.g.,
.png,.jpg) to skip non-image files:string[] imageFiles = Directory.GetFiles(GetSourceDirectory(), "*.*", SearchOption.TopDirectoryOnly) .Where(f => f.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)) .ToArray();
内容的提问来源于stack exchange,提问作者Austin L

