WriteableBitmap - Windows Event Handle Leak
- 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:

### 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
Assessment
This issue has not been assessed yet.