Syo*_*yon 2 c# dispose using image
我正在加载Image
一个byte[]
使用MemoryStream
并通过检查它来获取有关图像的信息ProperyItems
.在这样做的过程中,我注意到一些奇怪的行为,其中一些图像PropertyItems
正在消失.经过多次调试后,我终于发现这是由于MemoryStream
被处理造成的.
MemoryStream ms0 = new MemoryStream(imageBytes);
Image img0 = Image.FromStream(ms0);
Console.Out.WriteLine("Without using, Image propertyIDs: ");
foreach (int itemId in img0.PropertyIdList)
Console.Out.Write(itemId + ", ");
Console.Out.Write("\n");
Image img1 = null;
using (MemoryStream ms1 = new MemoryStream(imageBytes))
{
img1 = Image.FromStream(ms1);
}
Console.Out.WriteLine("Outside using, Image propertyIDs: ");
foreach (int itemId in img1.PropertyIdList)
Console.Out.Write(itemId + ", ");
Console.Out.Write("\n");
Run Code Online (Sandbox Code Playgroud)
输出:
Without using, Image propertyIDs:
254, 256, 257, 258, 259, 262, 269, 273, 274, 277, 278, 279, 282, 283, 284, 296,
Outside using, Image propertyIDs:
254, 256, 257, 258, 259, 262, 274, 277, 278, 284, 296,
Run Code Online (Sandbox Code Playgroud)
所以看来至少有一些PropertyItems
是由内容直接支持的MemoryStream
,解决方案是不处理它,或者我错了?
在调试这个问题的过程中虽然我注意到其他奇怪的东西,如果我访问块内的PropertyIdList
(或与图像有关的任何东西PropertyItems
)using
,在处理PropertyItems
后不会消失MemoryStream
.
Image img2 = null;
using (MemoryStream ms2 = new MemoryStream(imageBytes))
{
img2 = Image.FromStream(ms2);
int[] tmp = img2.PropertyIdList;
}
Console.Out.WriteLine("Outside using with PropertyIdList access, Image propertyIDs: ");
foreach (int itemId in img2.PropertyIdList)
Console.Out.Write(itemId + ", ");
Console.Out.Write("\n");
Run Code Online (Sandbox Code Playgroud)
输出:
Outside using with PropertyIdList access, Image propertyIDs:
254, 256, 257, 258, 259, 262, 269, 273, 274, 277, 278, 279, 282, 283, 284, 296,
Run Code Online (Sandbox Code Playgroud)
我查看了Image
类的源代码,并且该PropertyIdList
属性似乎没有保留PropertyItems
数据的本地副本,那么为什么在这种情况下处理PropertyItems
后保留MemoryStream
?
一般来说,处理MemoryStream是一件相当无用的事情.它本身没有任何可支配资源,它只是内存,而且已经由垃圾收集器管理.只有你使用了BeginRead/Write()方法并且它们还没有完成,这是你永远不会做的事情.
但它确实将CanRead()属性设置为false.这对你从MemoryStream加载的Bitmap对象非常致命.
接下来,当你继续使用Bitmap时,会发生什么是相当不可预测的.GDI +要求流保持可读的,它可以使用它以后,读取惰性方式的位图数据.最典型的情况是,当位图被绘制并且通常会因"一般错误"而相当可靠地使程序崩溃.
你找到了另一个角落案例,似乎只是认为没有更多的属性.这不是那么神秘,你真的关闭了流,所以它没有更多可能读取的属性.对于GDI +而言,它不会产生异常,但这并不常见.
只是摆脱使用声明,它没有做任何有用的事情.如果你担心无论如何处理流,那么你必须在不再使用Bitmap对象之后这样做.
归档时间: |
|
查看次数: |
1166 次 |
最近记录: |