如何在Windows或ASP.NET服务中绘制?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (13)

根据MSDN的说法,在Windows服务或ASP.NET服务的System.Drawing命名空间中使用类并不是一个好主意。现在我正在开发一个类库,它可能需要访问这个特定的名称空间(用于测量字体),但不能保证主机进程不是服务。

现在,如果System.Drawing不可用,我可以回退到最佳方法,但如果可能的话,我宁愿在System.Drawing中使用类。所以我想要做的是在runtume中确定System.Drawing是否安全,如果是,则使用它,否则回退到次优选项。

我的问题是:我怎么可能检测到System.Drawing是否可以安全使用?

我想我也应该

  • 检测当前进程是Windows服务还是ASP.NET服务
  • 检测GDI是否可用
  • 或者也许有一种方法可以问System.Drawing.dll本身,如果它可以安全地使用

不幸的是,我不能想出实现这些方法的方法。有人有什么主意吗?

提问于
用户回答回答于

为了消除任何混淆,System.Drawing 在ASP.NET和Services下工作,它只是不受支持。可能会出现高负载(耗尽非托管资源),内存或资源泄漏(执行不当或称为处理模式)和/或在没有桌面显示它们时弹出对话框的问题。

测试会照顾后者,监测会提醒你前者。但是,如果/当您遇到问题时,不要指望能够致电PSS并要求解决问题。

那么,你有什么选择?那么,如果你不需要一个完全支持的路线,并且你不期望极端的负荷 - 很多人都忽略了MSDN的警告,并且成功地使用了System.Drawing。他们中的一些人已经被咬伤,但比失败故事更有成就。

如果你想支持某些东西,那么你需要知道你是否在交互式运行。就我个人而言,我可能会将其留给托管应用程序以在某处或某处设置非交互式标志。毕竟,该应用程序处于确定他们是否处于托管环境和/或想要冒GDI +问题的最佳位置。

可以检查EntryAssembly以查看它是从ServiceBase继承的,还是尝试访问System.Console。对于ASP.NET,沿着相同的路线,检测HttpContext.Current应该足够了。

认为会有一种托管或p / invoke的方式来寻找一个桌面(我认为这实际上是所有这些的决定性因素)和/或AppDomain之外的东西,这些都会让你知道。但是,我不确定它是什么,而MSDN对它的启发不大。

拖动MSDN,我记得它实际上是一个Window Station(它托管桌面),这是这里的重要一点。有了这些信息,我就可以找到GetProcessWindowStation(),它返回当前窗口工作站的句柄。将该句柄传递给GetUserObjectInformation()将提供一个USEROBJECTFLAGS结构体,如果有可见桌面,则应该有一个带有WSF_VISIBLE的dwFlags。

或者,EnumWindowsStations会给你一个你可以检查的站列表 - WinSta0是一个交互式站点。

但是,是的,我仍然认为只是让应用程序设置一个属性或容易的路线....

我进入Environment.UserInteractive,其中MS 完成了上面描述的GetProcessWindowStation.我仍然建议委托给托管应用程序(他们可能希望得到更快,但略微风险更高的System.Drawing路径),但UserInteractive似乎是一个很好的默认设置,不需要自己进行调整。

用户回答回答于

尽管它没有得到官方的支持,但我已经在高容量的Web服务器(包括Web应用程序和Web服务)上广泛使用了System.Drawing类多年,而不会导致任何性能或可靠性问题。

我认为确定代码是否可以安全使用的唯一方法是使用{}语句测试,监视和包装具有外部资源的任何对象。

扫码关注云+社区