如何正确处理使用LINQ创建的对象

时间:2011-02-23 18:37:20

标签: .net linq dispose idisposable

我有以下方法创建一次性对象的实例。

Public Overridable Sub TransformXmlDocumentsToFileStream(ByVal stream As System.IO.Stream, ByVal xmlDocuments As IEnumerable(Of String), ByVal transformContext As XslTransformContext)
    Dim readers As IEnumerable(Of XmlReader) = _
        (From document In xmlDocuments _
         Select XmlReader.Create(New System.IO.StringReader(document)))

    With transformContext
         TransformXmlDocumentsToFileStream(stream, readers, transformContext)
    End With
End Sub

然后我用另一种方法迭代对象:

For Each reader In readers
    Using reader
        transform.Transform(reader, writer)
    End Using
Next

visual studio代码分析器发出警告:

  

CA2000:Microsoft.Reliability:在方法'TransformHelper.TransformXmlDocumentsToFileStream(Stream,IEnumerable(Of String),XslTransformContext)'中,对象'New StringReader(document)'未沿所有异常路径放置。在对所有引用超出范围之前,在对象'New StringReader(document)'上调用System.IDisposable.Dispose。

由于没有StringReader的引用,我无法将其放入使用块或以其他方式处置它。可以忽略这个警告吗?当读者超出范围并进行垃圾收集时,应该处理StringReader,对吗?

2 个答案:

答案 0 :(得分:0)

很抱歉c#中的答案。管理IDisposables的一种简单方法是使调用new的方法也调用Dispose。

List<StringReader> stringReaders = new List<StringReader>();
  //note: Select is deferred.  stringReaders is captured.
IEnumerable<XmlReader> readers =
  xmlDocuments.Select(document =>
  {
    StringReader sr = new System.IO.StringReader(document);
    stringReaders.Add(sr);
    return XmlReader.Create(sr);
  });
try
{
  //this method enumerates readers, causing all of the allocations.
  TransformXmlDocumentsToFileStream(stream, readers, transformContext);
}
finally
{
  foreach(StringReader x in stringReaders)
  {
    x.Dispose();
  }
}

答案 1 :(得分:0)

当对象碰巧被垃圾收集时,会调用

Dispose,这可能是在对象超出范围之后永远或很长时间。您应该明确处理StringReader

如果我的VB正确,你可以这样做

    Dim stringReaders As IEnumerable(Of System.IO.StringReader) = _
        (From document In xmlDocuments _
         Select New System.IO.StringReader(document)).ToList()

    Try
        Dim readers As IEnumerable(Of XmlReader) = _
            (From stringReader In stringReaders _
             Select XmlReader.Create(stringReader))
        With transformContext
            TransformXmlDocumentsToFileStream(stream, readers, transformContext)
        End With

    Finally
        For Each stringReader In stringReaders
            stringReader.Dispose()
        Next
    End Try