How can I prevent garbage collection when calling ShowDialog in the xaml window?

I have an application that uses a lot of memory, but so far I can not change this fact. My problem is that I have an operation that I would like to perform and provide a progress dialog, but it seems that displaying the xaml progress window causes GC.Collect to be called 10 times! Any ideas how I can optimize the opening of my progress window?

According to my Ants Profiler, calls leading to GC.Collect,

 System.Window.ShowDialog() -> .. .. System.Windows.Media.Imaging.BitmapSource.CreateCachedBitmap -> SafeMILHandle.UpdateEstimatedSize -> SafeMILHandleMemoryPressure.ctor -> MemoryPressure.Add -> MemoryPressure.ProcessAdd -> GC.Collect 
+1
performance c # memory xaml
Jan 29 '13 at 15:59
source share
4 answers

Garbage collection was caused by the initialization of the WPF icon. When I removed the icon property from xaml:

 <Window ... Icon="/CommonUI;component/Common/ProgressReporting/MyIcon.ico"> 

and instead initialized it in the constructor:

 public ProgressWindow() { InitializeComponent(); Icon = Properties.Resources.MyIcon.ToImageSource(); } 

the problem is gone.

The difference is that System.Window.UpdateIcon() no longer called during ShowDialog() . The UpdateIcon() call created a CachedBitmap for each image size in the icon file, which in turn called MemoryPressure.Add , and due to the high memory load, the application called GC.Collect for each new bitmap created.

This small change reduced the loading time of my progress dialog by 15 seconds when a large project is uploaded to the app!

0
Jan 30 '13 at 13:40
source share

There is also a solution that completely disables the memory image associated with the bitmap and subsequent garbage collection. This is more of a hack, but you can read about a similar problem here .

 typeof(BitmapImage).Assembly.GetType("MS.Internal.MemoryPressure").GetField("_totalMemory", BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, Int64.MinValue / 2); 

This way you avoid searching all over your code to find and change the initialization of the WPF icon. In addition, some controls, such as System.Windows.Forms.Integration.ElementHost , will implicitly add a bitmap related to memory pressure, regardless of how you initialize.

+2
Oct 16 '15 at 18:43
source share

Are you checking other stack questions related to the topic? There may be some tips you can use:

How to avoid garbage collection in a .NET application in real time?

+1
Jan 29 '13 at 20:46
source share



All Articles