.NET PrivateFontCollection - how to release file locks upon completion

I have a function that returns PrivateFontCollection:

Public Shared Function GetCustomFonts() As PrivateFontCollection Dim result = New PrivateFontCollection Dim customFontFiles = {"Garamond.TTF", "Garamond-Bold.TTF", "Garamond-Italic.TTF", "EurostileExtended-Roman-DTC.TTF"} For Each fontFile In customFontFiles result.AddFontFile(Hosting.HostingEnvironment.MapPath("/Includes/" & fontFile)) Next Return result End Function 

Then I use the function as follows:

 Using customFonts = Common.GetCustomFonts() ' Do some stuff here End Using 

I would expect the files to be released, but they are still locked: I get the following error: "The action could not be completed because the file is open on the System. Close the file and try again. '

Disabling a website in IIS does not help; we must recycle the application pool for its release.

Can anyone advise how to use PrivateFontCollection so that the files are released between them?

+6
source share
1 answer

As a workaround, I loaded the fonts into memory and used AddMemoryFont instead. See code below. Keep in mind that this is the first time I have touched unmanaged resources in .NET, so I cannot guarantee that memory management is lower in order.

 Imports System.Drawing.Text Imports System.Runtime.InteropServices Public Class CustomFontService Implements IDisposable Dim _fontBuffers As List(Of IntPtr) Dim _collection As PrivateFontCollection Public Sub New() _collection = New PrivateFontCollection _fontBuffers = New List(Of IntPtr) Dim customFontFiles = {"Garamond.TTF", "Garamond-Bold.TTF", "Garamond-Italic.TTF", "EurostileExtended-Roman-DTC.TTF"} For Each fontFile In customFontFiles Dim fontBytes = System.IO.File.ReadAllBytes(Hosting.HostingEnvironment.MapPath("/Includes/" & fontFile)) Dim fontBuffer As IntPtr = Marshal.AllocHGlobal(fontBytes.Length) Marshal.Copy(fontBytes, 0, fontBuffer, fontBytes.Length) _fontBuffers.Add(fontBuffer) _collection.AddMemoryFont(fontBuffer, fontBytes.Length) Next End Sub Public Function GetCustomFonts() As PrivateFontCollection Return _collection End Function #Region "IDisposable Support" Private disposedValue As Boolean ' To detect redundant calls ' IDisposable Protected Overridable Sub Dispose(disposing As Boolean) If Not Me.disposedValue Then If disposing Then ' TODO: dispose managed state (managed objects). End If For Each buf In _fontBuffers If (buf <> IntPtr.Zero) Then Marshal.FreeHGlobal(buf) End If Next ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below. ' TODO: set large fields to null. End If Me.disposedValue = True End Sub ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources. Protected Overrides Sub Finalize() ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above. Dispose(False) MyBase.Finalize() End Sub ' This code added by Visual Basic to correctly implement the disposable pattern. Public Sub Dispose() Implements IDisposable.Dispose ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above. Dispose(True) GC.SuppressFinalize(Me) End Sub #End Region End Class 
+1
source

Source: https://habr.com/ru/post/977445/


All Articles