[英].NET PrivateFontCollection - how to release file locks when finished
我有一個返回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
然后我使用如下函數:
Using customFonts = Common.GetCustomFonts()
' Do some stuff here
End Using
我希望文件將被釋放,但它們仍然被鎖定:我收到以下錯誤:'操作無法完成,因為文件在System中打開。 關閉文件,然后重試。
在IIS中關閉網站沒有幫助; 我們必須回收應用程序池才能發布它。
任何人都可以建議如何使用PrivateFontCollection以使文件在使用之間釋放?
作為一種解決方法,我將字體加載到內存中並使用“AddMemoryFont”代替。 見下面的代碼。 請記住,這是我第一次觸及.NET中的非托管資源,所以我不能保證下面的內存管理是可以的。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.