首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET PrivateFontCollection -如何在完成时释放文件锁

.NET PrivateFontCollection -如何在完成时释放文件锁
EN

Stack Overflow用户
提问于 2014-10-29 22:59:39
回答 1查看 997关注 0票数 6

我有一个函数,它返回一个PrivateFontCollection:

代码语言:javascript
复制
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

然后,我按照以下方式使用该函数:

代码语言:javascript
复制
Using customFonts = Common.GetCustomFonts()
    ' Do some stuff here
End Using

我希望文件会被释放,但它们仍然被锁定:我得到了以下错误:“由于文件在系统中打开,操作无法完成。请关闭该文件,然后再试一次。”

关闭IIS中的网站没有帮助;我们必须回收应用程序池才能发布。

有人能建议如何使用PrivateFontCollection,以便在使用之间释放文件吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-29 23:45:12

作为解决办法,我将字体加载到内存中,并使用“AddMemoryFont”代替。请参阅下面的代码。请记住,这是我第一次接触.NET中的非托管资源,所以我不能保证下面的内存管理是正常的。

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26642136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档