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

13 c# asp.net

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

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

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

有人有任何解决方案?

Fra*_*ger 10

停止使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的答案.不幸的是我只限于.Net 2. (3认同)

小智 6

对于任何有兴趣的人,我将使用的解决方案是单声道C#发行版中的Mono.Cairo库,而不是使用system.drawing.如果我只是将mono.cairo.dll,libcairo-2.dll,libpng13.dll和zlib1.dll文件从单声道的Windows版本拖到与我的可执行文件相同的文件夹中,那么我可以使用visual studio 2005在Windows中开发一切都很好.

更新 - 我已经完成了上述工作,并对应用程序进行了压力测试,现在它们似乎运行顺畅,并且使用最多200mb的内存来启动.很高兴.


Lou*_*nco 1

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

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

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

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