• .NET Core下使用System.Drawing?


    .NET Core是从3.0开始才支持System.Drawing的,在3.0之前我们用的是一个叫SixLabors.ImageSharp.Drawing的第三方的库来实现.NET Core上的绘图。当我们的系统升级到.NET Core 3.1之后,我就抛弃掉了SixLabors.ImageSharp.Drawing,使用了微软官方的System.Drawing,一来可以减少一个依赖包,二来我认为官方的东西应该更稳定可靠,更关键的一点是SixLabors.ImageSharp.Drawing一直是beta版……

    另外吐槽一下这个SixLabors.ImageSharp.Drawing,版本更迭中经常出现断层,使得升级它的版本常常需要改代码,不是什么好用的东西。

    切到System.Drawing后,一切运行良好,已有一年多的时间。这里需要提到的一点就是,要在Linux下正常使用System.Drawing需要mono项目的libgdiplus,github地址是:https://github.com/mono/libgdiplus,而mono不算是微软官方的东西,这么看的话System.Drawing也不够官方啊。

    而最近我们系统出问题了,程序直接崩溃,没有任何征兆,也无法预测,运行一两天就会出现。检查Linux的系统日志,发现如此:

    Jan 22 13:22:58 l-test njt.fms[5839]: *** Error in `/usr/bin/dotnet': corrupted size vs. prev_size: 0x00007f4a80030c90 ***
    Jan 22 13:22:58 l-test njt.fms[5839]: ======= Backtrace: =========
    Jan 22 13:22:58 l-test njt.fms[5839]: /lib64/libc.so.6(+0x7f3e4)[0x7f4d50cbc3e4]
    Jan 22 13:22:58 l-test njt.fms[5839]: /lib64/libc.so.6(+0x814db)[0x7f4d50cbe4db]
    Jan 22 13:22:58 l-test njt.fms[5839]: /lib64/libfontconfig.so.1(FcFontSetDestroy+0x42)[0x7f4a70a0d682]
    Jan 22 13:22:58 l-test njt.fms[5839]: /lib64/libgdiplus.so.0(+0x1448e)[0x7f4a7d00e48e]
    Jan 22 13:22:58 l-test njt.fms[5839]: /lib64/libgdiplus.so.0(GdipGetFontCollectionFamilyCount+0x36)[0x7f4a7d00eb56]
    Jan 22 13:22:58 l-test njt.fms[5839]: [0x7f4cdc6e0f09]
    Jan 22 13:22:58 l-test njt.fms[5839]: ======= Memory map: ========
    Jan 22 13:22:58 l-test njt.fms[5839]: 00400000-00411000 r-xp 00000000 fd:01 1314605                            /usr/share/dotnet/dotnet
    Jan 22 13:22:58 l-test njt.fms[5839]: 00610000-00611000 r--p 00010000 fd:01 1314605                            /usr/share/dotnet/dotnet
    Jan 22 13:22:58 l-test njt.fms[5839]: 00611000-00612000 rw-p 00011000 fd:01 1314605                            /usr/share/dotnet/dotnet
    Jan 22 13:22:58 l-test njt.fms[5839]: 010ef000-03022000 rw-p 00000000 00:00 0                                  [heap]
    Jan 22 13:22:58 l-test njt.fms[5839]: 7f4a68df6000-7f4a68df7000 ---p 00000000 00:00 0
    Jan 22 13:22:58 l-test njt.fms[5839]: 7f4a68df7000-7f4a695f7000 rw-p 00000000 00:00 0
    Jan 22 13:22:58 l-test njt.fms[5839]: 7f4a695f7000-7f4a695f8000 ---p 00000000 00:00 0
    Jan 22 13:22:58 l-test njt.fms[5839]: 7f4a695f8000-7f4a69df8000 rw-p 00000000 00:00 0
    Jan 22 13:22:58 l-test njt.fms[5839]: 7f4a69df8000-7f4a69df9000 ---p 00000000 00:00 0
    Jan 22 13:22:58 l-test njt.fms[5839]: 7f4a69df9000-7f4a6a5f9000 rw-p 00000000 00:00 0
    Jan 22 13:22:58 l-test njt.fms[5839]: 7f4a6a5f9000-7f4a6a609000 r-xp 00000000 fd:01 672887                     /usr/lib64/libGLX.so.0.0.0
    Jan 22 13:22:58 l-test njt.fms[5839]: 7f4a6a609000-7f4a6a809000 ---p 00010000 fd:01 672887                     /usr/lib64/libGLX.so.0.0.0
    Jan 22 13:22:58 l-test systemd[1]: njt.fms.service: main process exited, code=killed, status=6/ABRT
    Jan 22 13:22:58 l-test systemd[1]: Unit njt.fms.service entered failed state.
    Jan 22 13:22:58 l-test systemd[1]: njt.fms.service failed.

    是libgdiplus出问题无疑了,但问题在于这个错误无法重现,程序跑一两天才会出现,我们的程序间接使用了“GdipGetFontCollectionFamilyCount”函数,参数并无不妥,要解决就比较麻烦了。只能寻找变通方案,难不成要切回SixLabors.ImageSharp.Drawing?——还真是,我找到了微软官方的一段说明:

    地址:https://docs.microsoft.com/en-us/dotnet/api/system.drawing?view=dotnet-plat-ext-5.0

    它竟然不建议我们在ASP.NET Core中使用System.Drawing,而是另外推荐了ImageSharp,之前的努力都白费了,究其原因就是操作系统图形接口上的鸿沟,System.Drawing是一套针对GDI+的接口,GDI即Windows原生的图形接口,GDI+是对GDI的增强,比如能在底层使用DirectDraw来加速图形绘制,支持渐变色渲染和一些动画效果等,这套接口是针对Windows的,要在别的系统中实现这么一套接口有些难,底层实现有太多不一样,甚至在没有图形界面的Windows(Windows Server Core了解一下)中估计都成问题,所以官方也不保证System.Drawing一定好用,但由于GDI+的使用惯性很大,也不能完全把它舍弃,再说在一般的Windows环境下,开发个桌面程序啥的它是一点问题都没有的。

    我最后还是不得不把相关代码切回SixLabors.ImageSharp.Drawing,中间又改了不少东西,不算太难,但也有些工作量。

  • 相关阅读:
    linux字符设备文件的打开操作
    Linux用ps命令查找进程PID再用kill命令终止进程的方法
    Linux内核锁与中断处理
    写给大数据开发初学者的话
    zabbix监控系统客户端安装
    详解zabbix安装部署(Server端篇)
    Keepalived+Nginx架构整理版
    Nginx + Tomcat 动静分离实现负载均衡
    五个常用的Linux监控脚本代码
    16个Linux服务器监控命令
  • 原文地址:https://www.cnblogs.com/guogangj/p/14333634.html
Copyright © 2020-2023  润新知