C# GDI+;System.Drawing.Bitmap提供的错误参数间歇性无效

C# GDI+;System.Drawing.Bitmap提供的错误参数间歇性无效,c#,asp.net,C#,Asp.net,我在ASP.Net应用程序中有一些C#代码,可以执行以下操作: 位图bmp=新位图(11841900) 有时它会抛出一个异常“参数无效”。现在我一直在谷歌上搜索,显然GDI+因抛出随机异常而臭名昭著,很多人都遇到过这个问题,但没有人能解决它!我检查了系统,它有足够的RAM和交换空间。 现在在过去,如果我做一个“iisreset”,那么问题就消失了,但过几天它又回来了。但我不相信我造成了内存泄漏,因为正如我上面所说的,有大量的ram+交换可用 有人有解决方案吗?您不仅需要足够的内存,还需要连续的内

我在ASP.Net应用程序中有一些C#代码,可以执行以下操作:

位图bmp=新位图(11841900)

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


有人有解决方案吗?

您不仅需要足够的内存,还需要连续的内存。随着时间的推移,内存变得支离破碎,很难找到大的块。除了从较小的位图构建图像之外,没有很多好的解决方案

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

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


我见过的一种策略是预先分配一些大块内存(在您的例子中是位图),并将它们作为一个池(获取并返回到池中)。如果您只需要很短的一段时间,您可以在内存中保留一些并共享它们。

我刚收到microsoft支持部门的回复。显然,如果你看这里:

您可以看到它说“系统中的类。Windows或ASP.NET服务中不支持使用绘图命名空间。试图在这些应用程序类型中使用这些类可能会产生意外问题,例如服务性能降低和运行时异常。” 所以他们基本上对这个问题洗手不干了。 他们似乎承认.Net framework的这一部分不可靠。我有点失望


下一步-有人能推荐一个类似的库来打开gif文件,叠加一些文本,然后再次保存吗?

我在上下文中看到的所有内容都与内存泄漏/处理泄漏有关。我建议您重新审视代码

实际发生的情况是,即使您在前一行代码中创建了该图像,该图像也会在将来的某个随机点进行处理。这可能是因为内存/句柄泄漏(清除代码中的某些内容似乎有所改善,但不能完全解决此问题)

由于此错误发生在应用程序使用一段时间后,有时使用大量内存,有时不使用,我觉得垃圾收集器不遵守规则,因为与服务相关的一些特殊调整,这就是为什么Microsoft不处理此问题的原因


停止使用GDI+并开始使用WPF映像类(.NET 3.0)。这些是GDI+类的主要清理,并针对性能进行了调整。此外,它还建立了一个“位图链”,允许您以高效的方式轻松地在位图上执行多个操作

通过阅读更多关于

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

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 C#发行版中的Mono.Cairo库,而不是使用system.drawing。如果我只是简单地将mono.cairo.dll、libcairo-2.dll、libpng13.dll和zlib1.dll文件从windows版本的mono拖到与可执行文件相同的文件夹中,那么我就可以在windows中使用visual studio 2005进行开发,一切都很好


更新-我已经完成了上面的工作,并对应用程序进行了压力测试,现在它似乎运行顺利,启动时使用的内存减少了200 MB。非常高兴。

系统中的类。Windows或ASP.NET服务中不支持使用绘图命名空间


有关受支持的替代方案,请参见(),这是一个本机库,讽刺地说,System.Drawing是基于。

1184x1900x32位的位图是~9兆字节。对于可靠地要求连续块来说,这真的太多了吗?我想可能是这样,所以我确保调用system.bitmap对象上的Dispose函数,这不是解决了问题吗?