对象进行深拷贝时出现的问题,求解答

吃草的猪 2011-12-13 11:50:02
我写了一个从缓存中返回一个对象的深拷贝的方法,代码如下。
现在的问题是,当一个人操作页面的时候是不会有问题的,当两个或者多个人同时操作这个页面的时候,偶尔会出现 未将对象设置到引用 之类的错误提示。
经过测试,错误就是出现在 return formatter.Deserialize(memoryStream); 这句代码上,但我仔细检查了,memoryStream是有值的,并且出错时的指针是指在位置88处。我也没有用到多线程之类的代码,究竟问题是出在哪里呢?


MemoryStream memoryStream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));

try
{
formatter.Serialize(memoryStream, HttpRuntime.Cache.Get("object_1"));
//memoryStream.Seek(0, SeekOrigin.Begin);

//反序列化至另一个对象
memoryStream.Position = 0;
return formatter.Deserialize(memoryStream);
}
catch //(Exception ex)
{
throw new Exception(memoryStream.Position);
}
finally
{
memoryStream.Position = 0;

//关闭流
memoryStream.Flush();
memoryStream.Close();
}
...全文
2197 43 打赏 收藏 转发到动态 举报
写回复
用AI写文章
43 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿非 2011-12-15
  • 打赏
  • 举报
回复
那加锁控制一下把
吃草的猪 2011-12-15
  • 打赏
  • 举报
回复
用上LOCK以后确实就不出错了。
尽管没有从根本上解决问题,不过还是谢谢各位,特别是 Sandy945,让您费心了。
东邪独孤 2011-12-15
  • 打赏
  • 举报
回复
因为在多人操作的时候,可能同时存在向流写入和从流中读出同时进行的情况。
因为每次序列化的时候,指针重新定位到0,接下来向0向面一直往下写,刚好这个时候,有人来读数据,反序更化,刚好,序列化写了一半,反序列化读了一半,两个操作都没有完成,这时候流中的字节就乱套了,都不知道是哪个对象了,
所以,在流的读写过程夹在Application.Lock()和Application.UnLock()之间,保证在同一时间,只有一个用户在操作。
阿非 2011-12-14
  • 打赏
  • 举报
回复
if (HttpRuntime.Cache.Get("object_" + s_Name) == null)
=》
if ((obj_Return=HttpRuntime.Cache.Get("object_" + s_Name)) == null)

在存的时候也要判断存的内容是否为null
吃草的猪 2011-12-14
  • 打赏
  • 举报
回复
就我目前的代码写法来看,您觉得导致obj_Return为空的问题大概是出在那里呢?
因为我每次从缓存里面取出来使用的时候都是采用序列化和反序列化的深拷贝的,除了把对象加入缓存的时候,其他也没有地方对缓存里面的值进行操作了。
或者您看下,我在哪里做些修改可以解决这个问题?谢谢了

try
{
obj_Return = HttpRuntime.Cache.Get("object_1");
formatter.Serialize(memoryStream, obj_Return );
memoryStream.Position = 0;
obj_Return = formatter.Deserialize(memoryStream);
return obj_Return;
}
阿非 2011-12-14
  • 打赏
  • 举报
回复
那就说明 obj_Return 为null了
吃草的猪 2011-12-14
  • 打赏
  • 举报
回复
catch //(Exception ex)
{
memoryStream.Position = 0;//加了这句

StreamReader sr = new StreamReader(memoryStream);
string s = sr.ReadToEnd();

throw new Exception("序列化时出错,类型为:" + obj_Return.GetType() + "," + s);

sr.Close();
}
出现的错误提示变成了:序列化时出错,类型为:DataEntity.C_DataMg_News,���� ADataEntity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

中间还有乱码。。
阿非 2011-12-14
  • 打赏
  • 举报
回复
你定位到0 再重新读下
吃草的猪 2011-12-14
  • 打赏
  • 举报
回复
catch //(Exception ex)
{
StreamReader sr = new StreamReader(memoryStream);
string s = sr.ReadToEnd();

throw new Exception("序列化时出错,类型为:" + obj_Return.GetType() + "," + s);

sr.Close();
}
是不是说明在出错的时候,memoryStream已经是空的了,但为什么我输出Position时是指在88位上的呢?
吃草的猪 2011-12-14
  • 打赏
  • 举报
回复
楼上的,用这个办法读出来,显示字符串为空。。。。
吃草的猪 2011-12-14
  • 打赏
  • 举报
回复
错误肯定是出在formatter.Deserialize(memoryStream);这一句上,因为我之前对每句代码分别try{}catch{}了,就是在这一句出的错。
根据之前catch里面对出错时变量的值判断,应该是memoryStream这个值有问题。但这个值在缓存中的新增和读取都是在固定几个地方进行的,理论上不该出错。
是不是缓存中的那个类的值在读出以后的某个时间变化了?
阿非 2011-12-14
  • 打赏
  • 举报
回复
不是这个信息。

是错误在什么时候出现,用锁可以解决问题。

但如果分析原因 就可能不用锁解决
吃草的猪 2011-12-14
  • 打赏
  • 举报
回复
出现错误的时候,如果有catch的,是显示抛出的内容,如果没有catch的,就显示 未将对象引用设置到对象的实例
阿非 2011-12-14
  • 打赏
  • 举报
回复
错误出现的时机 有更多的信息么
吃草的猪 2011-12-14
  • 打赏
  • 举报
回复
改成上面这样了,然后存入的时候也对类加了不为空的判断,结果还是一样。。。
绿领巾童鞋 2011-12-13
  • 打赏
  • 举报
回复
说实话,不会。
序列化的对象所占的内存空间是不是确定的?
恩,顶一个
阿非 2011-12-13
  • 打赏
  • 举报
回复
StreamReader sr = new StreamReader(memoryStream);
string s = sr.ReadToEnd();
sr.Close();

看s
吃草的猪 2011-12-13
  • 打赏
  • 举报
回复
01000255 25525525 51000000012200065 68971169769110116105116121443286101 11411510511111061494648464846484432671171081161171141016111010111711611 4971084432801179810810599751011218411110710111061110117108108
吃草的猪 2011-12-13
  • 打赏
  • 举报
回复
输出结果是一串数字,这边发不上来,提示 回复中存在非法字符!
加载更多回复(22)

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧