我有一个.NET 3.5应用程序,使用PrivateFontCollection.AddMemoryFont将字体加载到内存中,并使用这些字体生成图像。最近我在Windows Server 2012 R2上安装了它,但会出现间歇性错误。
这个问题可以通过以下方法来说明:
private Bitmap getImage(byte[] fontFile)
{
using (PrivateFontCollection fontCollection = new PrivateFontCollection())
{
IntPtr fontBuffer = Marshal.AllocCoTaskMem(fontFile.Length);
Marshal.Copy(fontFile, 0, fontBuffer, fontFile.Length);
fontCollection.AddMemoryFont(fontBuffer, fontFile.Length);
Bitmap image = new Bitmap(200, 50);
using (Font font = new Font(fontCollection.Families[0], 11f, FontStyle.Regular))
{
using (Graphics graphics = Graphics.FromImage(image))
{
graphics.DrawString(String.Format("{0:HH:mm:ss}", DateTime.Now), font, Brushes.White, new PointF(0f, 0f));
}
}
return image;
}
}
在Windows 7上,这个功能一直都能正常工作。但是在Windows Server 2012 R2上,如果使用超过一个字体反复调用它,它就会失败。例如:
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Arial.ttf"));
这个功能即使被调用了数百次,也能正常工作,但是如果使用多种字体进行调用:
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Wingding.ttf"));
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Arial.ttf"));
这段代码在最开始的几个调用(约20个)时工作正常,但之后会开始产生随机结果(第二次调用有时会返回带有wingdings字体的文本图像——即混淆了字体)。
我偶尔(很少)在DrawString调用中遇到“GDI+中发生通用错误”。
在Windows 7上没有出现任何这些错误。
我尝试了各种清理选项,但都没有成功。
作为一种解决方法,我尝试将字体文件写入磁盘,然后使用AddFontFile加载,但是(在Windows 2012 R2上),字体文件将被锁定整个进程的生命周期,因此无法删除。这使得这个选项是不可接受的。
如何让AddMemoryFont始终工作,或让AddFontFile解锁文件,任何帮助都将不胜感激。