2014-10-29 33 views
6

Mam funkcji, która zwraca PrivateFontCollection:NET PrivateFontCollection - Jak zwolnić blokady plików po zakończeniu

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 

I wtedy korzystać z funkcji w następujący sposób:

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

Spodziewam się, że pliki zostaną zwolnione, ale nadal są zablokowane: Pojawia się następujący błąd: "Nie można ukończyć działania, ponieważ plik jest otwarty w systemie. Zamknij plik i spróbuj ponownie. "

Zamykanie strony w IIS nie pomaga; musimy odtworzyć pulę aplikacji, aby została zwolniona.

Czy ktoś może doradzić, jak korzystać z PrivateFontCollection w taki sposób, aby pliki były publikowane w różnych zastosowaniach?

+0

Jedynym moim dotychczasowym pomysłem jest załadowanie czcionki do pamięci i użycie w zamian opcji AddMemoryFont. W ten sposób mogę zagwarantować, że PrivateFontCollection nigdy nie dotknie plików. – extremeandy

+0

Aby uzyskać możliwą odpowiedź, spójrz na http://stackoverflow.com/questions/26671026/how-to-delete-the-file-of-a-privatefontcollection-addfontfile – Horcrux7

+0

Dodano błąd połączenia https://connect.microsoft.com/ VisualStudio/feedback/details/1379843 – Peter

Odpowiedz

1

W ramach obejścia problemu załadowałem czcionki do pamięci i zamiast tego użyłem "AddMemoryFont". Zobacz kod poniżej. Pamiętaj, że po raz pierwszy dotknąłem niezarządzanych zasobów w .NET, więc nie mogę zagwarantować, że zarządzanie pamięcią poniżej jest w porządku.

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