locked
Font Caching Change from 8.0 to 8.1 RRS feed

  • Question

  • I have an app that writes a font file to a temp folder and then points (XAML) TextBlock and Glyphs elements at it.  The TextBlock and Glyphs elements use the font just fine.  The displaying of the text has no problems.

    In response to user actions, the XAML tree being displayed eventually gets torn down and replaced by a new one that will use entirely different font temp files.  Once the XAML tree is torn down, all the font temp files being referenced by that tree are then deleted.  This process was all debugged and seemed to be working fine under 8.0.  I did originally (under 8.0) run into problems with attempting to delete the temp files before the XAML tree was torn down and not being able to delete the files because they were still in use.  That was all fixed.

    Under 8.1 it appears "something" is now keeping a handle open on the temp font files even after the XAML tree is torn down.  My code is unable to delete the files, and I cannot delete the files from File Explorer until the application is terminated.

    Was there a change in 8.1 where a font cache (or something) is now keeping the font file open when under 8.0 it was being released once the XAML referencing it was torn down?

    I've even tried using GC.WaitForPendingFinalizers() following the XAML tear down before trying to delete the files.  It doesn't seem to matter.

    It is also the case the if I just catch and ignore the exception thrown when trying to delete the temp font files, the code will proceed to displaying the new XAML tree just fine.  At that point, given a bit of a pause on my part, all the garbage clean-up, etc, should eventually come to completion and I should be able to delete the files using File Explorer.  However that isn't the case.  The files appear to remain open regardless of how long (within reason) they are left no longer in use.

    If there is new font caching in effect, is there any way to either suppress it for my temp fonts or otherwise get the temp font files closed?

    Later...

    TextBlock and RichTextBlock do not appear to create a problem.  After TextBlock and RichTextBlock references to a given font are removed from the XAML tree, the font file can be deleted.  Only Glyphs appears to create the problem.  It didn't "seem" to under 8.0 or perhaps an earlier version of .NET for 8.0.  Were changes made to Glyphs and perhaps it is failing to release its font reference now?  Perhaps in combination with using myGlyphs.Indices?

    Thanks!


    -- kburgoyne


    • Edited by kburgoyne Thursday, November 21, 2013 6:18 AM More info
    Wednesday, November 20, 2013 7:16 PM

Answers

  • Fixed:

    Glyphs XAML element appears to retain a reference to a font file until its finalizer is called.  GC.WaitForPendingFinalizers() does not actually cause finalizers to be called.  It is first necessary to call GC.Collect() to initiate garbage clean-up, which then initiated the calling of finalizers.  At that point, GC.WaitForPendingFinalizers() can be called to wait for all the finalizers to finished being called.  After that, any discarded Glyphs objects will have released their font file reference.

    This having to force the call to the Glyphs finalizer did not "seem" to be necessary under Windows 8.0, or perhaps an earlier version of .NET married to Windows 8.0.  It's possible it was technically necessary, but other characteristics of the execution environment may have always previously caused the Glyphs finalizer to be called before my code attempted to delete the temp font file.

    Glyphs myGlyphs = new Glyphs(); myGlyphs.FontUri = new Uri("URI of font file"); // ... do other initialization of myGlyphs // When done using myGlyphs: myGlyphs = null; GC.Collect(); GC.WaitForFinalizers(); // At this point Glyphs will have released its reference to "URI of font file" file.


    -- kburgoyne

    • Marked as answer by kburgoyne Thursday, November 21, 2013 7:18 AM
    Thursday, November 21, 2013 7:17 AM

All replies

  • Fixed:

    Glyphs XAML element appears to retain a reference to a font file until its finalizer is called.  GC.WaitForPendingFinalizers() does not actually cause finalizers to be called.  It is first necessary to call GC.Collect() to initiate garbage clean-up, which then initiated the calling of finalizers.  At that point, GC.WaitForPendingFinalizers() can be called to wait for all the finalizers to finished being called.  After that, any discarded Glyphs objects will have released their font file reference.

    This having to force the call to the Glyphs finalizer did not "seem" to be necessary under Windows 8.0, or perhaps an earlier version of .NET married to Windows 8.0.  It's possible it was technically necessary, but other characteristics of the execution environment may have always previously caused the Glyphs finalizer to be called before my code attempted to delete the temp font file.

    Glyphs myGlyphs = new Glyphs(); myGlyphs.FontUri = new Uri("URI of font file"); // ... do other initialization of myGlyphs // When done using myGlyphs: myGlyphs = null; GC.Collect(); GC.WaitForFinalizers(); // At this point Glyphs will have released its reference to "URI of font file" file.


    -- kburgoyne

    • Marked as answer by kburgoyne Thursday, November 21, 2013 7:18 AM
    Thursday, November 21, 2013 7:17 AM
  • Hi, kburgoyne

    Thank for your answer!

    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Thursday, November 21, 2013 8:41 AM