使用未释放的内存流返回对象会导致内存泄漏吗?

3
我遇到了一个类似于这样的例程,它会执行以下操作:
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);
}

我希望在这种情况下可以使用“using”关键字,但不确定它是否能够正常工作:

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

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

2

你对第一种方法没有调用 msDispose 方法感到担忧,这是正确的。作为良好的实践,你应该始终调用实现了 IDisposable 接口的对象的 Dispose 方法。

我建议采用最后一种方法。你可以放心使用 using 语句来释放对象,即使在中间返回时也能按预期处理。

下面是代码在运行时的运行情况:首先,将评估返回表达式,然后执行 try-finally 块(其中using 语句仅是语法糖),最后方法将返回。

唯一可能遇到问题的情况是在 using 语句内部返回变量本身当然,如果你保留任何引用超出 using 块的范围,这也会导致问题。

还请参见:关于从 using 块返回的最佳做法


@LukeH:我不确定我理解你的意思。C#规范指出,在处理流对象的finally块之前,将首先评估返回表达式,因此无论Bitmap构造函数决定做什么都是无关紧要的。 - Cody Gray
3
我错了,但不是那种错法。如果你关闭/释放流,Bitmap可能会损坏。从MSDN上可以看到:"必须在Bitmap的生命周期内保持数据流开放状态。" http://msdn.microsoft.com/en-us/library/z7ha67kw.aspx - LukeH
@LukeH:啊,好的。我以前从没注意过这一点。你现在有什么理由相信这不会引起任何问题和/或上述代码能够正常工作的事实不仅仅是依赖于实现细节? - Cody Gray
在我的原始评论中,我说 Bitmap 类不应该/不会这样做,因为这是个坏习惯。但很不幸,我错了,因为它确实这样做了。(可能它内部持有流的引用,然后稍后重复使用它,而不是在第一次调用构造函数时急切地将流转换为 byte[] 或其他形式。) - LukeH
使用 return (new Bitmap(ms).Clone(rect,pixFormat)) 可以“绕过”在原始 BMP 生命周期期间需要打开流的要求吗? - ptnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接