GDI + System.Drawing.Bitmap给出错误参数无效间歇性

时间:2020-03-06 14:41:52  来源:igfitidea点击:

我在ASP.Net应用程序中有一些Ccode可以做到这一点:

位图bmp =新位图(1184,1900);

有时会引发异常"参数无效"。现在我一直在搜索,显然GDI +因引发随机异常而臭名昭著,很多人都遇到了这个问题,但是没有人能解决!我已经检查了系统,它具有足够的RAM和交换空间。
现在在过去,如果我执行" iisreset",那么问题就消失了,但是几天后又回来了。但是我不相信我造成了内存泄漏,因为正如我上面所说,有很多ram + swap free。

有人有什么解决方案吗?

解决方案

我们不仅需要足够的内存,而且还必须是连续的。随着时间的流逝,内存变得零散,并且很难找到大块。除了从较小的位图构建图像外,没有很多好的解决方案。

新的Bitmap(x,y)几乎只需要分配内存-假设程序没有以某种方式损坏(是否有任何不安全的代码可能破坏堆),那么我将从分配失败开始。看似小的分配可能会失败,因此需要一个连续的块。堆的碎片化通常是使用自定义分配器解决的-我认为这在IIS中(或者可能)不是一个好主意。

要查看内存出现什么错误,请尝试分配一个巨大的位图作为测试-看看它会抛出什么错误。

我见过的一种策略是预分配一些大的内存块(在情况下是位图),并将它们视为池(获取并返回到池中)。如果仅在短时间内需要它们,则可能只需保留一些内存并共享它们就可以摆脱困境。

我刚刚收到Microsoft支持的回复。显然,如果我们在这里看:

http://msdn.microsoft.com/en-us/library/system.drawing.aspx

我们会看到它说:"不支持在Windows或者ASP.NET服务中使用System.Drawing命名空间中的类。尝试从这些应用程序类型之一中使用这些类可能会产生意外的问题,例如服务性能下降和运行时异常。"
因此,他们基本上是在洗手。
他们似乎承认.Net框架的这一部分不可靠。我有点失望

接下来,有人可以推荐类似的库来打开gif文件,叠加一些文本并再次保存吗?

到目前为止,我在上下文中看到的所有内容都与内存泄漏/句柄泄漏有关。我建议我们重新审视代码。

实际发生的情况是,即使我们在上一行代码中创建了图像,该图像也会在将来随机放置。这可能是由于内存/句柄泄漏(清除我的代码中的某些内容似乎可以改善但不能完全解决此问题)。

因为此错误是在应用程序使用了一段时间后发生的,有时会使用大量的内存,有时却没有,所以我觉得垃圾收集器由于与服务相关的一些特殊调整而没有遵守规则,这就是Microsoft洗涤它们的原因手中有这个问题。

http://blog.lavablast.com/post/2007/11/The-Mysterious-Parameter-Is-Not-Valid-Exception.aspx

停止使用GDI +,然后开始使用WPF Imaging类(.NET 3.0)。这些是对GDI +类的主要清理,并针对性能进行了调整。此外,它还建立了一个"位图链",使我们可以轻松高效地对位图执行多项操作。

阅读有关BitmapSource的更多信息

这是一个从空白位图开始等待接收一些像素的示例:

using System.Windows.Media.Imaging;
class Program {
    public static void Main(string[] args) {
        var bmp = new WriteableBitmap(1184, 1900, 96.0, 96.0, PixelFormat.Bgr32, null);
    }
}

对于任何有兴趣的人,我要使用的解决方案是来自mono Cdistribution的Mono.Cairo库,而不是使用system.drawing。如果我只是将mono版本的Windows版本中的mono.cairo.dll,libcairo-2.dll,libpng13.dll和zlib1.dll文件拖到与我的可执行文件相同的文件夹中,则可以使用Visual Studio 2005和一切都很好。

更新我已经完成了上面的工作,并对该应用程序进行了压力测试,它现在似乎都可以顺利运行,并且最多可以使用200 mb的RAM进行启动。很高兴。