【问题标题】:Returning an Object with Non-Disposed Memory Stream causes memory leaks?返回具有非处置内存流的对象会导致内存泄漏?
【发布时间】:2011-01-05 18:16:35
【问题描述】:

我遇到过这样的例程:

static public Bitmap byte2bmp(byte[] BitmapData)
{
    MemoryStream ms = new MemoryStream(BitmapData);
    return (new Bitmap(ms));
}

我担心这可能不是最好的推荐方法。在这种情况下,ms 是否被正确处理?

或者将结果分配给临时位图,处理流,然后返回临时对象会更好吗?

static public Bitmap byte2bmp(byte[] BitmapData)
{
    MemoryStream ms = new MemoryStream(BitmapData);
    Bitmap temp=new Bitmap(ms);
    ms.Dispose();
    return (temp);
}

我希望在这种情况下可以使用“使用”,但不确定它是否会正常运行:

static public Bitmap byte2bmp(byte[] BitmapData)
{
    using(MemoryStream ms = new MemoryStream(BitmapData))
    {
    return (new Bitmap(ms));
    }
}

什么是最有效/最合适的解决方案?谢谢!

【问题讨论】:

    标签: c# dispose using


    【解决方案1】:

    您担心第一种方法无法处理ms 是正确的。作为一种良好做法,您应该始终对实现 IDisposable 的对象调用 Dispose 方法。

    我建议采用最后一种方法。您可以确信 using 语句将按预期处理对象,即使您在对象中间返回。

    以下是代码在运行时如何分解:首先,返回表达式将被计算,然后 try-finally 块(using statement 只是语法糖)将被执行,最后该方法将返回。

    using 语句中间可能遇到返回问题的唯一情况是if you return the variable from the using statement itself。当然,如果您保留对超出using 块范围的变量的任何引用,这无论如何都会导致问题。

    另见:Best practice regarding returning from using blocks

    【讨论】:

    • @LukeH:我不确定我理解你的意思。 C# 规范表明返回表达式将在处理流对象处置的 finally 块之前首先被评估,因此无论 Bitmap 构造函数决定做什么都无关紧要。
    • 我错了,但不是那样。如果您关闭/处置流,Bitmap可能会中断。来自 MSDN:“您必须在 Bitmap 的生命周期内保持流打开。” msdn.microsoft.com/en-us/library/z7ha67kw.aspx
    • @LukeH:啊,好吧。我以前从未注意到这一点。您现在有什么理由相信这不会导致任何问题和/或上述代码有效的事实不仅仅是依赖于实现细节?
    • 在我最初的评论中,我说过 Bitmap 类不应该/不会这样做,因为这是不好的做法。我错了,因为它确实如此,不幸的是。 (大概它在内部持有对流的引用,然后在以后重新使用它,而不是在第一次调用构造函数时急切地将流转换为byte[] 或其他任何东西。)
    • 会使用 return (new Bitmap(ms).Clone(rect,pixFormat)) “绕过”在原始 BMP 生命周期内打开流的要求吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    • 2011-01-26
    • 2011-11-14
    • 2016-01-17
    • 1970-01-01
    • 2010-12-20
    相关资源
    最近更新 更多