.net C# DataTable序列化多线程问题
2011-04-11 11:58
471 查看
最近在项目中遇到一个bug,调了好久,也查了好久,今天终于搞定了!
在 System.Data.DataTable.SerializeDataTable(SerializationInfo info, StreamingContext context, Boolean isSingleTable, SerializationFormat remotingFormat)
在 System.Data.DataTable.GetObjectData(SerializationInfo info, StreamingContext context)
在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
在 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)
在 BitAuto.AutoCommune.CacheManager.CacheContext.WriteDataToDisk[T](String businessDic, String cacheKeyDic, String strkey, T data)
以上是异常信息。。。
最后结果是,.netFramwork 的一个bug。DataTable不支持多线程序列化 。
在对DataTable进行序列化时,需要这个DataTable依附在一个DataSet上面,如果DataTable.DataSet为空,则会创建 一个临时的DataSet对象并把需要序列化的DataTable加到DataSet上面,等序列化好了,再把DataSet移掉(不知道微软为什么要这 么设计)。
问题就来了,如果有多个线程在对同一个DataTable进行序列化时,就有可能会出现线程间的同步化问题。原因是在对DataSet.Tables集合进行增加、移除时,没有考虑到多线程问题,从而可能导致上文异常。 为了解决这个问题,一个变通的方法是给需要序列化的DataTable显示地指定一个DataSet,这样序列化时就不需要创建临时的DataSet,可不会有多线程的问题了。
DataSet myDS = new DataSet("MyDataSet");
myDS.Tables.Add(myTable); // myTable即是要序列化的DataTable对象。
本人总结:在msdn上看到这句话:DataSet类
该类型对于多线程读操作是安全的。您必须使任何写操作同步。
意思是DataSet类的读操作是线程安全的,但是写操作是不安全的。此Bug中如果给每个DataTable指定一个DataSet的话,.net就不会为每一个DataTable指定临时DataSet,而恰恰这样会出现DataSet的增加、修改等写操作(线程不安全的)!为每一个DataTable指定自己DataSet就只有读操作(线程安全的)!
所以也不能说是。netFramework的bug,因为DataTable和DataSet都是读操作线程安全的。而此时。net序列化DataTable时又需要临时DataSet支持,造成此问题出现,是我们不太了解。net的内部机制,误用而已!
原文地址:
http://blog.163.com/yinson_lin/blog/static/2212017201002935926117/ 参考地址:
http://kbalertz.com/903645/exception-occurs-instance-DataSet-typed-object-serialized-multiple-threads-access-instance-DataSet-typed-object-synchronously.aspx
在 System.Data.DataTable.SerializeDataTable(SerializationInfo info, StreamingContext context, Boolean isSingleTable, SerializationFormat remotingFormat)
在 System.Data.DataTable.GetObjectData(SerializationInfo info, StreamingContext context)
在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
在 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)
在 BitAuto.AutoCommune.CacheManager.CacheContext.WriteDataToDisk[T](String businessDic, String cacheKeyDic, String strkey, T data)
以上是异常信息。。。
最后结果是,.netFramwork 的一个bug。DataTable不支持多线程序列化 。
在对DataTable进行序列化时,需要这个DataTable依附在一个DataSet上面,如果DataTable.DataSet为空,则会创建 一个临时的DataSet对象并把需要序列化的DataTable加到DataSet上面,等序列化好了,再把DataSet移掉(不知道微软为什么要这 么设计)。
问题就来了,如果有多个线程在对同一个DataTable进行序列化时,就有可能会出现线程间的同步化问题。原因是在对DataSet.Tables集合进行增加、移除时,没有考虑到多线程问题,从而可能导致上文异常。 为了解决这个问题,一个变通的方法是给需要序列化的DataTable显示地指定一个DataSet,这样序列化时就不需要创建临时的DataSet,可不会有多线程的问题了。
DataSet myDS = new DataSet("MyDataSet");
myDS.Tables.Add(myTable); // myTable即是要序列化的DataTable对象。
本人总结:在msdn上看到这句话:DataSet类
该类型对于多线程读操作是安全的。您必须使任何写操作同步。
意思是DataSet类的读操作是线程安全的,但是写操作是不安全的。此Bug中如果给每个DataTable指定一个DataSet的话,.net就不会为每一个DataTable指定临时DataSet,而恰恰这样会出现DataSet的增加、修改等写操作(线程不安全的)!为每一个DataTable指定自己DataSet就只有读操作(线程安全的)!
所以也不能说是。netFramework的bug,因为DataTable和DataSet都是读操作线程安全的。而此时。net序列化DataTable时又需要临时DataSet支持,造成此问题出现,是我们不太了解。net的内部机制,误用而已!
原文地址:
http://blog.163.com/yinson_lin/blog/static/2212017201002935926117/ 参考地址:
http://kbalertz.com/903645/exception-occurs-instance-DataSet-typed-object-serialized-multiple-threads-access-instance-DataSet-typed-object-synchronously.aspx
相关文章推荐
- paip.c#.net 多线程调用控件的问题
- .net中前台javascript与后台c#函数相互调用问题
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 能支撑10万以上客户端的数据同步下载问题
- [C#][ASP.NET]DataSet,DataTable(DataSet)导出至指定XLS,DBF模版
- C#.net OutputCache 产生的严重配置问题 找不到指定的数据库
- Visual C#.NET编程 常见问题集锦
- C#.net XML的序列化与反序列化
- Asp.Net Core Mvc上Json序列化首字母大小写的问题
- 转 C# , ASP.Net 中 关于 like in 实现参数化查询的问题
- C#.NET解析XML(使用属性控制 XML 序列化)
- 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! C#/ASP.Net 实现!
- C#[Serializable]在C#中的作用-NET 中的对象序列化
- Serializable在C#中的作用.net中的对象序列化 (转)
- C# 多线程 注意问题 总结
- C#.NET解析XML(使用属性控制 XML 序列化)
- 【转】c#中使用多线程访问winform中控件的若干问题
- net中前台javascript与后台c#函数相互调用问题
- (转)C#.NET如何不序列化字段、属性
- C#垃圾回收问题--》多线程的不安全性--》单例模式
- JSON之Asp.net MVC C#对象转JSON,DataTable转JSON,List<T>转JSON,JSON转List<T>,JSON转C#对象