XML序列化在VB.Net中产生内存不足错误
我将尽力提供尽可能多的必要细节。在投票否决我之前,请询问更多细节。 我们正在尝试序列化一个对象,该对象内部有一个名为ObjList的CollectionBase属性。下面所涉及的课程示例 调用Serialize函数时,我们使用XmlTextWriter序列化对象,然后在写入程序填充的MemoryStream上使用StreamReader.ReadToEnd读入字符串对象。 在尝试从内存流读取时,我们会出现“内存不足”错误 MemoryStream.Length显示略多于2亿字节。正在序列化的对象在其ObjList属性类型CollectionBase中有17922个对象,每个对象都有一个ObjList,其中包含可变数量的数据 以下是序列化代码:XML序列化在VB.Net中产生内存不足错误,xml,vb.net,serialization,Xml,Vb.net,Serialization,我将尽力提供尽可能多的必要细节。在投票否决我之前,请询问更多细节。 我们正在尝试序列化一个对象,该对象内部有一个名为ObjList的CollectionBase属性。下面所涉及的课程示例 调用Serialize函数时,我们使用XmlTextWriter序列化对象,然后在写入程序填充的MemoryStream上使用StreamReader.ReadToEnd读入字符串对象。 在尝试从内存流读取时,我们会出现“内存不足”错误 MemoryStream.Length显示略多于2亿字节。正在序列化的对象
Public Class XMLserializer(Of T)
Public _serializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
'... Some other code
Public Function Serialize(ByVal myobject As T) As String
'Reset local varaible to actual object type
_serializer = New System.Xml.Serialization.XmlSerializer(myobject.GetType)
'serialise to a memory stream, then read into a string
Try
Dim result As String = Nothing
If myobject IsNot Nothing Then
Using ms As New MemoryStream
Using xtw As New XmlTextWriter(ms, System.Text.Encoding.UTF8)
xtw.Formatting = Formatting.Indented
_serializer.Serialize(xtw, myobject)
'rewind
ms.Seek(0, System.IO.SeekOrigin.Begin)
Using reader As New StreamReader(ms, Text.Encoding.UTF8)
result = reader.ReadToEnd()
xtw.Close()
reader.Close()
End Using
End Using
End Using
End If
Return result
Catch ex As Exception
Throw
End Try
End Function
末级
以下是我的对象定义:
<Serializable()> _
Public Class SLMR_ObjList(Of T)
Inherits Collections.CollectionBase
Implements IList(Of T)
'.... Properties and Methods
End Class
' Location objects
<Serializable()> _
Public Class LocationCollection
Private _serializer As XMLserializer(Of LocationCollection) = Nothing
Private _locationList As SLMR_ObjList(Of Location)
Public Property LocationList As SLMR_ObjList(Of Location)
Get
If _locationList Is Nothing Then
_locationList = New SLMR_ObjList(Of Location)
End If
Return _locationList
End Get
Set(ByVal value As SLMR_ObjList(Of Location))
_locationList = value
End Set
End Property
Public Sub Search_EquipNotInspected() 'As String
Dim ds As DataSet = Nothing
Dim dt As DataTable = Nothing
Try
Me.ObjList.Clear()
ds = DAO_AS400_ELVPLOC00.SearchForEquipNotInspected(_search_counties,
_search_fromdate,
_search_todate)
dt = ds.Tables(0)
If dt.Rows.Count > 0 Then
For Each dr As DataRow In dt.Rows
Dim curLocation As AS400_ELVPLOC00
' Check and load the current location, or create new entry
curLocation = Me.ObjList.FindByProperty("ID", dr.Item("LocID"))
If IsNothing(curLocation) OrElse curLocation.ID = 0 Then
curLocation = New AS400_ELVPLOC00
With curLocation
.ID = dr.Item("LocID")
.Address1 = dr.Item("Addr1")
' ...
End With
Me.ObjList.Add(curLocation)
End If
Dim curEquipment As New AS400_ELVPEQP00
With curEquipment
.ID = dr.Item("EquipID")
.ELBLDGCD = dr.Item("ELBLDGCD")
' ...
End With
curLocation.AS400_ELVPEQP_COL.ObjList.Add(curEquipment)
Next
End If
Catch ex As Exception
'TO DO: Handle Exception
Finally
If Not ds Is Nothing Then
ds.Dispose()
End If
End Try
End Sub
Public Function XMLDATA() As String
Return XMLSerialize(Me)
End Function
Public Shared Function XMLSerialize(ByVal myobject As LocationCollection) As String
If _serializer Is Nothing Then
_serializer = New XMLserializer(Of LocationCollection)
End If
Return _serializer.Serialize(myobject)
End Function
End Class
<Serializable()> _
Public Class Location
Private _id As Integer
Public Property ID As Integer
Get
Return _id
End Get
Set(ByVal value As Integer
_id = value
End Set
End Property
Private _address1 As String
Public Property Address1 As String
Get
Return _address1
End Get
Set(ByVal value As String
_address1 = value
End Set
End Property
'.... other values
Private _equipCollection As EquipmentCollection
Public Property EquipCol As EquipmentCollection
Get
If _equipCollection Is Nothing Then
_equipCollection = New EquipmentCollection
End If
Return _equipCollection
End Get
Set(ByVal value As EquipmentCollection)
_equipCollection = value
End Set
End Property
End Class
' Equipment objects
<Serializable()> _
Public Class EquipmentCollection
Private _equipmentList As SLMR_ObjList(Of Equipment)
Public Property EquipmentList As SLMR_ObjList(Of Equipment)
Get
If _equipmentList Is Nothing Then
_equipmentList = New SLMR_ObjList(Of Equipment)
End If
Return _equipmentList
End Get
Set(ByVal value As SLMR_ObjList(Of Equipment))
_equipmentList = value
End Set
End Property
End Class
<Serializable()> _
Public Class Equipment
Private _id As Integer
Public Property ID As Integer
Get
Return _id
End Get
Set(ByVal value As Integer
_id = value
End Set
End Property
Private _equipManuf As String
Public Property Manufacturer As String
Get
Return _equipManuf
End Get
Set(ByVal value As String
_equipManuf = value
End Set
End Property
Private _equipLocation As Location
Public Property EquipLocation As Location
Get
If _equipLocation Is Nothing Then
_equipLocation = New Location
End If
Return _equipLocation
End Get
Set(ByVal value As Location
_equipLocation = value
End Set
End Property
End Class
有了34000条记录,我们就会出现内存不足的错误。如果我们使用<2000条记录,它就可以工作。有没有想过如何找出我们为什么会出错?Try/Catch-Throw-End-Catch-End-Try什么都不做。仅供参考,您不应该使用新的XmlTextReader或XmlTextWriter。自.NET 2.0以来,它们一直被弃用。请改用XmlReader.Create或XmlWriter.Create。谢谢。我正在使用XmlWriter.Create。此外,Try/Catch为我在调试期间捕获线程提供了一个位置。有没有更有效的方法来实现这一点?在我测试时,我获取了主对象,并遍历了集合,对每个对象进行了XML序列化。正如我所做的,ad将它们附加到StringBuilder对象。StringBuilder长度=183324697,当我尝试执行StringBuilder.ToString时,我得到System.OutOfMemoryException,因此它一定是太多数据了。但是为什么呢?我们使用的是32位系统。。。我想我可以拿到2147483647,或者至少1073741823。我在这里实际使用的限制是什么?我认为可以将调试器设置为在特定类型的未处理异常上中断。在任何情况下,如果你只是在评论说,这是调试的目的,这将使我高兴。
Dim locCollection As New LocationCollection
'.... set object's search properties
locCollection.Search_EquipNotinspected() ' Gets 34002 records, which works out to 17922 Location objects
Dim xml As String = locCollection.XMLDATA