2014-10-29 9 views
6

Ho una funzione che restituisce un PrivateFontCollection:.NET PrivateFontCollection - come liberare i blocchi di file quando finito

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 

Ho quindi utilizzare la funzione come segue:

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

Mi aspetterei che il i file verrebbero rilasciati, ma sono ancora bloccati: ottengo il seguente errore: 'L'azione non può essere completata perché il file è aperto in Sistema. Chiudi il file e riprova. '

La chiusura del sito Web in IIS non aiuta; dobbiamo riciclare il pool di app da rilasciare.

Qualcuno può consigliare su come utilizzare PrivateFontCollection in modo tale che i file vengano rilasciati tra gli usi?

+0

La mia unica idea è quella di caricare il carattere in memoria e utilizzare invece AddMemoryFont. In questo modo posso garantire che PrivateFontCollection non tocchi mai i file. – extremeandy

+0

Per una possibile risposta, consultare http://stackoverflow.com/questions/26671026/how-to-delete-the-file-of-a-privatefontcollection-addfontfile – Horcrux7

+0

Aggiunto bug di connessione https://connect.microsoft.com/ VisualStudio/retroazione/dettagli/1379843 – Peter

risposta

1

Come soluzione temporanea, ho caricato i caratteri in memoria e invece ho usato "AddMemoryFont". Vedi il codice qui sotto. Tieni presente che questa è la prima volta che ho toccato risorse non gestite in .NET, quindi non posso garantire che la gestione della memoria qui sotto sia OK.

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