您的位置:首页 > 移动开发 > Objective-C

[问题记录.dotnet]对象当前正在其他地方使用(Object is currently in use elsewhere) - Image.Save

2017-02-27 14:48 405 查看
今天有同事反馈了个问题。查看日志,是在通讯框架这层序列化报错,异常消息为“对象当前正在其他地方使用“。查看异常的堆栈,是Image.Save方法引发的。

经过简单排查,满足这些条件时会出现问题:1)返回对象中,Image类型字段的值非空且都是指向同一个Image实例;2)并发调用。

进行单独验证,测试代码如下:

[Serializable]
public class ImageTest
{
System.Drawing.Image m_val;

public System.Drawing.Image Val
{
get { return m_val; }
set { m_val = value; }
}
}
Image img = System.Drawing.Image.FromFile(@"D:\about.png");
Thread thread1 = new Thread(new ThreadStart(() =>
{
byte[] bytes;
try
{
for (int i = 0; i < 10; i++)
{
ImageTest obj = new ImageTest();
obj.Val = img;
using (MemoryStream stream = new MemoryStream())
{
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(stream, obj);
bytes = stream.ToArray();
}
}
}
catch (Exception ex)
{
//...
}
Console.WriteLine("end.");
}));
Thread thread2 = new Thread(new ThreadStart(() =>
{
byte[] bytes;
try
{
for (int i = 0; i < 10; i++)
{
ImageTest obj = new ImageTest();
obj.Val = img;
using (MemoryStream stream = new MemoryStream())
{
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(stream, obj);
bytes = stream.ToArray();
}
}
}
catch (Exception ex)
{
//...
}
Console.WriteLine("end.");
}));
thread1.Start();
thread2.Start();


异常:

Type:    System.InvalidOperationException
Message: 对象当前正在其他地方使用
Object is currently in use elsewhere

StackTrace:
在 System.Drawing.Image.get_RawFormat()
在 System.Drawing.Image.Save(MemoryStream stream)
在 System.Drawing.Image.System.Runtime.Serialization.ISerializable.GetObjectData(SerializationInfo si, StreamingContext context)
在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
...


原因:Image.Save 方法不是线程安全的(很多GDI+的方法都不是线程安全的)。同时、对同一个Image对象实例进行处理,就可能会导致线程异常。

建议:对返回值的类型做调整:如果Image字段必须要,改用byte[]类型。

备注:其他地方遇到这个错误,可能是加锁,以确保线程安全。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  异常 .NET
相关文章推荐