Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7183157
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T17:55:22+00:00 2026-05-28T17:55:22+00:00

I have an app with a Master-Details view. When you select an item from

  • 0

I have an app with a Master-Details view. When you select an item from the ‘master’ list, it populates the ‘details’ area with some images (created via RenderTargetBitmap).

Each time I select a different master item from the list, the number of GDI handles in use by my app (as reported in Process Explorer) goes up – and eventually falls over (or sometimes locks up) at 10,000 GDI handles in use.

I’m at a loss on how to fix this, so any suggestions on what I’m doing wrong (or just suggestions on how to get more information) would be greatly appreciated.

I’ve simplified my app down to the following in a new WPF Application (.NET 4.0) called “DoesThisLeak”:

In MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        ViewModel = new MasterViewModel();
        InitializeComponent();
    }

    public MasterViewModel ViewModel { get; set; }
}

public class MasterViewModel : INotifyPropertyChanged
{
    private MasterItem selectedMasterItem;

    public IEnumerable<MasterItem> MasterItems
    {
        get
        {
            for (int i = 0; i < 100; i++)
            {
                yield return new MasterItem(i);
            }
        }
    }

    public MasterItem SelectedMasterItem
    {
        get { return selectedMasterItem; }
        set
        {
            if (selectedMasterItem != value)
            {
                selectedMasterItem = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("SelectedMasterItem"));
                }
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class MasterItem
{
    private readonly int seed;

    public MasterItem(int seed)
    {
        this.seed = seed;
    }

    public IEnumerable<ImageSource> Images
    {
        get
        {
            GC.Collect(); // Make sure it's not the lack of collections causing the problem

            var random = new Random(seed);

            for (int i = 0; i < 150; i++)
            {
                yield return MakeImage(random);
            }
        }
    }

    private ImageSource MakeImage(Random random)
    {
        const int size = 180;
        var drawingVisual = new DrawingVisual();
        using (DrawingContext drawingContext = drawingVisual.RenderOpen())
        {
            drawingContext.DrawRectangle(Brushes.Red, null, new Rect(random.NextDouble() * size, random.NextDouble() * size, random.NextDouble() * size, random.NextDouble() * size));
        }

        var bitmap = new RenderTargetBitmap(size, size, 96, 96, PixelFormats.Pbgra32);
        bitmap.Render(drawingVisual);
        bitmap.Freeze();
        return bitmap;
    }
}

In MainWindow.xaml

<Window x:Class="DoesThisLeak.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="900" Width="1100"
        x:Name="self">
  <Grid DataContext="{Binding ElementName=self, Path=ViewModel}">
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="210"/>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <ListBox Grid.Column="0" ItemsSource="{Binding MasterItems}" SelectedItem="{Binding SelectedMasterItem}"/>

    <ItemsControl Grid.Column="1" ItemsSource="{Binding Path=SelectedMasterItem.Images}">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <Image Source="{Binding}"/>
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>
  </Grid>
</Window>

You can reproduce the problem if you click on the first item in the list, then hold down the Down cursor key.

From looking at !gcroot in WinDbg with SOS, I can’t find anything keeping those RenderTargetBitmap objects alive, but if I do !dumpheap -type System.Windows.Media.Imaging.RenderTargetBitmap it still shows a few thousand of them that haven’t been collected yet.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T17:55:23+00:00Added an answer on May 28, 2026 at 5:55 pm

    TL;DR: fixed. See the bottom. Read on for my journey of discovery and all the wrong alleys I went down!

    I’ve done some poking around with this, and I don’t think it’s leaking as such. If I beef up the GC by putting this either side of the loop in Images:

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

    You can step (slowly) down the list and see no change in the GDI handles after a few seconds.
    Indeed, checking with MemoryProfiler confirms this – no .net or GDI objects leak when moving slowly from item to item.

    You do get into trouble moving quickly down the list – I saw process memory heading past 1.5G and the GDI object climbing to 10000 when it hit a wall. Every time MakeImage was called after that, a COM error was thrown and nothing useful could be done for the process:

    A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in PresentationCore.dll
    A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in PresentationCore.dll
    A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
    System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=SelectedMasterItem; DataItem='MasterViewModel' (HashCode=28657291); target element is 'ListBox' (Name=''); target property is 'SelectedItem' (type 'Object') COMException:'System.Runtime.InteropServices.COMException (0x88980003): Exception from HRESULT: 0x88980003
       at System.Windows.Media.Imaging.RenderTargetBitmap.FinalizeCreation()
    

    This, I think explains why you see so many RenderTargetBitmaps hanging around. It also suggests to me a mitigation strategy – assuming it’s a framework/GDI bug. Try to push the render code (RenderImage) into a domain which will allow the underlying COM component to be restarted. Initially, I’d try a thread in it’s own apartment (SetApartmentState(ApartmentState.STA)) and if that didn’t work, I’d try an AppDomain.

    However, it’d be easier to try to deal with the source of the problem, which is allocating so many images so quickly, because even if I get it up to 9000 GDI handles and wait a bit, the count falls right back down to the baseline after the next change (it seems to me as there’s some idle processing in the COM object which needs a few seconds of nothing, and then another change to release all of it’s handles)

    I don’t think there are any easy fixes for this – I’ve tried adding a sleep to slow the movement down, and even calling ComponentDispatched.RaiseIdle() – neither of these have any effect. If I had to make it work this way, I’d be trying to run the GDI processing in a restartable way (and dealing with the errors which would occur) or changing the UI.

    Depending on the requirements in the detail view, and most importantly, the visibility and size of the images in the right hand side, you could take advantage of the ability of the ItemsControl to virtualise your list (but you probably have to at least define the height and number of the contained images so it can manage the scrollbars properly). I suggest returning an ObservableCollection of images, rather than an IEnumerable.

    In fact, having just tested that, this code appears to make the problem go away:

    public ObservableCollection<ImageSource> Images
    {
        get 
        {
            return new ObservableCollection<ImageSource>(ImageSources);
        }
    }
    
    IEnumerable<ImageSource> ImageSources
    {
        get
        {
            var random = new Random(seed);
    
            for (int i = 0; i < 150; i++)
            {
                yield return MakeImage(random);
            }
        }
    }
    

    The main thing this gives the runtime, as far as I can see, is the number of items (which the enumerable, obviously, does not) meaning that it neither has to enumerate it multiple times, or guess (!). I can run up and down the list with my finger on the cursor key without this blowing 10k handles, even with 1000 MasterItems, so it looks good to me. (My code has no explicit GC either)

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have created split view based ipad app, where master view is table view
In my iPhone Core Data app I have it configured in a master-detail view
I have a simple app I am messing around with its a basic Master/Details
I have a split view-based app that presents a master-detail interface, and uses a
i have app with splitviewcontroller , in master view of splitview i have uitableview
I am trying the master-detail presentation in my app: when an item in a
I have a Console App created in VS 2010 targeting .NET 4.0. According to
I have storyboard and implement master detail application app ,when i assign manuel class
I have a UISplitViewController in an iPad app. When something is selected from the
I have a Cocoa app with a similar layout like Mail.app: A source list

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.