Skip to content

Race condition in ImageCodecInfoHelper #130348

Description

@Pat28

Description

When 2 threads try to save a bitmap via Image.Save(Stream, ImageFormat), one of the two threads fails with a
System.ArgumentNullException : Value cannot be null. (Parameter 'encoder')

The reason for this is an allocated s_encoders static field on ImageCodecInfoHelper, but it has no values in the array yet.
See this image where the array is created and assigned to s_encoders but populated later.
The array should be created and assigned to a temporary variable and when all array elements have been set assigned to s_encoders
Image

Reproduction Steps

Run the following repeatedly and it will raise an Exception once in a while.

void Main()
{
var bitmaps = new List();
for (var i = 0; i < 10; i++)
{
bitmaps.Add(new Bitmap(100, 100));
}

Parallel.ForEach(bitmaps, bitmap =>
{
	using var stream = new MemoryStream();
	bitmap.Save(stream, ImageFormat.Png);
});

foreach (var bitmap in bitmaps)
{
	bitmap.Dispose();
}

}

Expected behavior

s_encoders should have a proper value for every element in it.

Actual behavior

s_encoders can be returned in thread B, while thread A is still busy populating its items

Regression?

No response

Known Workarounds

In our example we can workaround it by creating a Bitmap and saving it to a dummy stream once,
This guarantees the s_encoders is being populated properly.

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions