GDI+ MeasureString 引发的AccessViolationException
2012-07-25 20:23
761 查看
最近在用xna开发游戏 然后自己写了个xnaFont和StringGraphics类
突然一天晚上 这段代码开始报错了
然后google查了下 有说APIbug的 有说显卡问题的
最后解决方案也很出乎意料
最原始的出错原因是 因为字体Font的实例错误的被CLR回收。
基于GDI字体的工作流程如下:
> 初始化一个GDI的Bitmap作为buffer 并且创造graphics
> 初始化一个xna的Texture2D作为buffer
> 初始化一个GDI的Font 这步有如下可能:
> 使用构造函数Font(string familyName, float emSize) 通过字体名寻找系统字体
> 使用构造函数Font(FontFamily family, float emSize) 通过FontFamily的实例来构造字体
而这个FontFamily可以通过如下代码从文件中读取:
PrivateFontCollection font = new PrivateFontCollection(); font.AddFontFile(fontFileName); return font.Families[0];
于是就出现了一个问题
如果把这段代码写成函数 返回FontFamily
那么这个新创建出来的PrivateFontCollection对象就会被回收掉
连带着它内部的Families也被回收掉了
此时应用到这个FontFamily的Font就会出现问题 导致最最最上面的那个奇怪的错误
最后解决方案是 对每一个PrivateFontCollection对象用一个静态的List进行保存就OK了
只要存在引用数就不会给GC带走
另外实际上用一个PrivateFontCollection对象也可以多次读取字体文件
而且它会自动过滤掉已读取过的family
不过真的这样设计的话反而会出现问题
因为考虑重复读取的话 从已读取的family中找出最后读取的是个麻烦事 它不一定是数组的最后一个
相关文章推荐
- commonDialog引发AccessViolationException的一种原因
- C#:AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。解决办法收集
- System.AccessViolationException类型的未经处理的异常在System.Data.dll中发
- System.AccessViolationException”类型的第一次机会异常在 System.Data.dll 中发生 其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
- JVM 出了问题 EXCEPTION_ACCESS_VIOLATION
- JVM经典问题EXCEPTION_ACCESS_VIOLATION(亲测可用)
- 我的异常-VS2012“System.AccessViolationException: 尝试读取或写入受保护的内存。”
- “System.AccessViolationException”类型的未经处理的异常在 System.Drawing.dll 中发生,尝试读取或写入受保护的内存。这通常指示其他内存已损坏
- System.AccessViolationException: Attempted to read or write protected memory This is often an indication that other memory is corrupt
- 未处理AccessViolationException 异常
- Access violation reading location 0x00000004--Visual Studio 2010中GetMenu()和GetSubMenu(0)引发异常的一个简单解决方法
- 连接数据库及出现System.AccessViolationException错误的解决方法
- First-chance exception at 0x000007FE86D99B3C in XXXX.exe: 0xC0000005: Access violation reading locat
- System.AccessViolationException”类型的未经处理的异常在 System.Data.dll 中发生。其它信息:尝试读取或写入受保护的内存。这通常指示其它内存已损坏。
- 何解决这样的错误 EXCEPTION_ACCESS_VIOLATION
- 【Emit基础】System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
- 我异常-VS2012“System.AccessViolationException: 试图读取或写入保护内存。”
- System.AccessViolationException,尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
- 遇到"Unhandled exception in app.exe (QTGUID4.DLL): 0xC0000005: Access Violation"错误的解决过程
- 【C#】AccessViolationException