【问题标题】:GDI+ System.Drawing.Bitmap gives error Parameter is not valid intermittentlyGDI+ System.Drawing.Bitmap 给出错误参数间歇性无效
【发布时间】:2008-09-25 00:27:34
【问题描述】:

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

位图 bmp = new Bitmap(1184, 1900);

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

有人有解决办法吗?

【问题讨论】:

    标签: c# asp.net


    【解决方案1】:

    停止使用 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);
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      更新 - 我已经完成了上述操作,并对应用程序进行了压力测试,现在一切似乎运行顺利,并且启动时使用的内存减少了 200mb。很开心。

      【讨论】:

        【解决方案3】:

        迄今为止,我在上下文中看到的所有内容都与内存泄漏/句柄泄漏有关。我建议你换一双新的眼睛来研究你的代码。

        实际发生的情况是,图像会在未来随机放置,即使您已经在前一行代码中创建了它。这可能是因为内存/句柄泄漏(从我的代码中清除一些似乎有所改善,但不能完全解决此问题)。

        因为这个错误是在应用程序使用一段时间后出现的,有时会使用大量内存,有时不会,我觉得垃圾收集器不遵守规则是因为一些与服务相关的特殊调整,这就是为什么微软解决了这个问题。

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

        【讨论】:

        • 我认为可能是这样,所以我确保我在 system.bitmap 对象上调用了 Dispose 函数,那不是解决了问题吗?
        【解决方案4】:

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

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

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

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

        【讨论】:

        • 1184x1900x32bits 的位图约为 9 兆。可靠地要求连续块真的太多了吗?
        【解决方案5】:

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

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

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

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

        【讨论】:

          【解决方案6】:

          System.Drawing 命名空间中的类不支持在 Windows 或 ASP.NET 服务中使用

          有关受支持的替代方案,请参阅 Windows Imaging Components (msdn),具有讽刺意味的是 System.Drawing 所基于的本机库。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-09
            • 1970-01-01
            • 1970-01-01
            • 2020-07-10
            • 1970-01-01
            相关资源
            最近更新 更多