【发布时间】:2023-03-11 18:55:01
【问题描述】:
我有一些代码可以做
MemoryStream ms = new MemoryStream();
...
return Image.FromStream(ms);
它以非常折衷的方式失败,因为 Image 对象不持有流的引用,因此如果 GC 启动导致 GDI+ 错误,它可以被释放。
我该如何解决这个问题(无需将流保存到磁盘,或更改我的方法信号)?
【问题讨论】:
我有一些代码可以做
MemoryStream ms = new MemoryStream();
...
return Image.FromStream(ms);
它以非常折衷的方式失败,因为 Image 对象不持有流的引用,因此如果 GC 启动导致 GDI+ 错误,它可以被释放。
我该如何解决这个问题(无需将流保存到磁盘,或更改我的方法信号)?
【问题讨论】:
这对我来说似乎不太可能 - 几乎任何使用 Image.FromStream 都会导致问题。
在我看来更有可能是某些东西正在处理您的 MemoryStream,这是不应该的。
您能否提供一个简短但完整的程序来演示该问题?强制垃圾收集应该使其相对容易重现 - 你甚至可以创建自己的类,从 MemoryStream 派生,并使用终结器来显示它是否真的被收集(嗯,至少完成了) .
【讨论】:
read 应该总是大于 0 - 但它很容易小于 buffer.Length,即使有更多之后数据仍在流中。
如果不稍微更改代码,就没有办法做到这一点。 Remarks section for the documentation for the static FromStream method on the Image class states:
您必须保持流打开 图片的生命周期。
话虽如此,您必须确保在图像访问流时,流是打开的。看起来(通过反射器查看)FromImage 方法实际上并没有导致 Image 实例保留对从中加载图像的 Stream 的引用。
话虽这么说,您可以以某种方式将图像和 MemoryStream(或 Stream)链接在一起,这样它就不会被 GCed。如果不真正保留图像的“所有权”(它被传递),那么我建议您创建一个数据结构来保存对 Image 和 Stream 的引用,并将两者一起传递。
【讨论】: