dotnet / dotnet/wpf

WriteableBitmap - Windows Event Handle Leak

Open
#5,978 1 comment 2 reactions 1 assignee Claimed by @singhashish-wpf View on GitHub
Investigate Performance
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

### Description

When creating a `System.Windows.Media.Imaging.WriteableBitmap` within a `System.Threading.Thread`, windows handles (Type: Event; Auto Reset/Manual Reset) are not deleted after thread has exited.

WinDbg `!handle 0 ff` example output:

Handle 2ff8
Type Event
Attributes 0
GrantedAccess 0x1f0003:
Delete,ReadControl,WriteDac,WriteOwner,Synch
QueryState,ModifyState
HandleCount 2
PointerCount 32769
Name
Object Specific Information
Event Type Auto Reset
Event is Waiting
Handle 2ffc
Type Event
Attributes 0
GrantedAccess 0x1f0003:
Delete,ReadControl,WriteDac,WriteOwner,Synch
QueryState,ModifyState
HandleCount 2
PointerCount 32769
Name
Object Specific Information
Event Type Manual Reset
Event is Waiting

Finalized object types:
![image](https://user-images.githubusercontent.com/66618936/150821366-af78b041-c532-4996-bb7f-6b90177ce6bb.png)

### Reproduction Steps

while (true)
{
var thread = new System.Threading.Thread(() => {
var bitmap = new System.Windows.Media.Imaging.WriteableBitmap(10, 10, 96, 96, System.Windows.Media.PixelFormats.Pbgra32, null);
bitmap.Freeze();
});
thread.Start();
thread.Join();

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}

### Expected behavior

After the thread has finished its execution and GC is forced, the thread and managed/unmanaged resources of the `WriteableBitmap` have to be released, keeping the `Handle`-count kind of constant.

### Actual behavior

Handles created in `WriteableBitmap` are not deleted. Even though objects of type `BitmapSourceSafeMILHandle`/`SafeMILHandle` are finalized, it appears that `MS.Win32.HwndSubclass` remain in memory. Leading to steadily growing `Handle`-count and filling of the ATOM table.

### Regression?

_No response_

### Known Workarounds

_No response_

### Configuration

- .NET Framework 4.8, .NET Core 5
- Windows 10/11 Pro/Home
- x64

### Other information

- It seems like the 'leak' only happens once per thread, since creating many `WriteableBitmap`s in a single thread does not lead to the same behaviour.
- The `WriteableBitmap.Dispatcher` appears to be null.
- `WriteableBitmap.Freeze()` has not impact.
- Slowing down the creation does not help.
- Using `BitmapSource.Create(...)` (base class) does not increase handle count.
- In production it occured by creating `WriteableBitmap`s using a `System.Threading.Timer` (a lot slower, maybe due to a newly created thread in certain circumstances).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.