C# 如何处置MemoryStream对象

C# 如何处置MemoryStream对象,c#,.net,dispose,memorystream,C#,.net,Dispose,Memorystream,下面的代码用于将现有PDF缝合在一起[顺便说一句,我们使用TallComponents进行实际缝合,以防您想知道什么是PDFUtility: PDFUtility.Document docFinal = new PDFUtility.Document(); PDFUtility.Document docToAdd = null; byte[] combinedFile; foreach (byte[] content in fileContents) { MemoryStream fi

下面的代码用于将现有PDF缝合在一起[顺便说一句,我们使用TallComponents进行实际缝合,以防您想知道什么是
PDFUtility

PDFUtility.Document docFinal = new PDFUtility.Document();
PDFUtility.Document docToAdd = null;
byte[] combinedFile;

foreach (byte[] content in fileContents)
{
    MemoryStream fileContentStream = new MemoryStream(content);
    docToAdd = new PDFUtility.Document(fileContentStream);
    docFinal.Pages.AddRange(docToAdd.Pages.CloneToArray());
}
using (MemoryStream stream = new MemoryStream())
{
    docFinal.Write(stream);
    combinedFile = stream.ToArray();
}
此代码的突出问题是以下命令:

MemoryStream fileContentStream = new MemoryStream(content);
内存流
fileContentStream
没有得到处理,可能(我相信)占用资源的时间比需要的时间长

显而易见的解决方案是使用块将MemoryStream的创建封装在
中。代码将如下所示:

PDFUtility.Document docFinal = new PDFUtility.Document();
PDFUtility.Document docToAdd = null;
byte[] combinedFile;

foreach (byte[] content in fileContents)
{
    using (MemoryStream stream = new MemoryStream())
    {
        MemoryStream fileContentStream = new MemoryStream(content);
        docToAdd = new PDFUtility.Document(fileContentStream);
        docFinal.Pages.AddRange(docToAdd.Pages.CloneToArray());
    }
}
using (MemoryStream stream = new MemoryStream())
{
    docFinal.Write(stream);
    combinedFile = stream.ToArray();
}
在上述代码中使用using块会导致代码在这一行失败(因为流之前已被释放):

一种可能的解决方案是跟踪所有MemoryStream实例,并在它们使用完毕后进行处理。以下是代码:

PDFUtility.Document docFinal = new PDFUtility.Document();
PDFUtility.Document docToAdd = byte[] combinedFile;
List<MemoryStream> streams = new List<MemoryStream>();
foreach (byte[] content in fileContents)
{
    MemoryStream fileContentStream = new MemoryStream(content);
    streams.Add(fileContentStream); //EACH INSTANCE OF A STREAM IS TRACKED
    docToAdd = new PDFUtility.Document(fileContentStream);
    docFinal.Pages.AddRange(docToAdd.Pages.CloneToArray());
}
using (MemoryStream stream = new MemoryStream())
{
    docFinal.Write(stream);
    combinedFile = stream.ToArray();
}
streams.ForEach(s => s.Dispose()); //DISPOSE OF ALL STREAMS HERE
PDFUtility.Document docFinal=新的PDFUtility.Document();
PDFUtility.Document doctodd=字节[]组合文件;
列表流=新列表();
foreach(fileContents中的字节[]内容)
{
MemoryStream fileContentStream=新的MemoryStream(内容);
streams.Add(fileContentStream);//跟踪流的每个实例
docToAdd=新的PDF.Document(fileContentStream);
docFinal.Pages.AddRange(docoadd.Pages.CloneToArray());
}
使用(MemoryStream stream=new MemoryStream())
{
docFinal.Write(流);
combinedFile=stream.ToArray();
}
streams.ForEach(s=>s.Dispose())//在这里处理所有的溪流
上面的代码有效。我只是把处理推迟到最后文件写完之后


然而,这似乎不是“最佳”解决方案。是否有任何方法可以实现使用块(从而保证对象被正确地处理?

使用块对于
try finally
块来说,只不过是语法上的糖分而已

根据使用块的使用方式,您最终会得到两种类型的try-finally块

案例1:

// This code ...
using( var thing = new Thing() ) {
    thing.DoOperation();
}

// ... turns into this scoped try-finally:
{
    var thing = new Thing();
    try {
        thing.DoOperation();
    }
    finally {
        thing.Dispose();
        thing = null;
    }
}
案例二:

// This code ...
var thing = new Thing();
using( thing ) {
    thing.DoOperation();
}

// ... turns into this code
var thing = new Thing();
try {
    thing.DoOperation();
}
finally {
    thing.Dispose();
    // Note the lack of a null assignment.
}
有了这些知识,您可以修改第三个解决方案以使用
finally
块,以确保始终清理
内存流
对象

PDFUtility.Document docFinal = new PDFUtility.Document();
PDFUtility.Document docToAdd = byte[] combinedFile;
List<MemoryStream> streams = new List<MemoryStream>();

try 
{
    foreach (byte[] content in fileContents)
    {
        MemoryStream fileContentStream = new MemoryStream(content);
        streams.Add(fileContentStream); //EACH INSTANCE OF A STREAM IS TRACKED
        docToAdd = new PDFUtility.Document(fileContentStream);
        docFinal.Pages.AddRange(docToAdd.Pages.CloneToArray());
    }
    using (MemoryStream stream = new MemoryStream())
    {
        docFinal.Write(stream);
        combinedFile = stream.ToArray();
    }

}
finally 
{
    streams.ForEach(s => s.Dispose()); //DISPOSE OF ALL STREAMS HERE
}
PDFUtility.Document docFinal=新的PDFUtility.Document();
PDFUtility.Document doctodd=字节[]组合文件;
列表流=新列表();
尝试
{
foreach(fileContents中的字节[]内容)
{
MemoryStream fileContentStream=新的MemoryStream(内容);
streams.Add(fileContentStream);//跟踪流的每个实例
docToAdd=新的PDF.Document(fileContentStream);
docFinal.Pages.AddRange(docoadd.Pages.CloneToArray());
}
使用(MemoryStream stream=new MemoryStream())
{
docFinal.Write(流);
combinedFile=stream.ToArray();
}
}
最后
{
streams.ForEach(s=>s.Dispose());//在此处处理所有流
}

在退出循环之前,是否有任何类型的
docFInal.Flush
方法可以调用?请参阅。还有一个方法(似乎更活跃)@TonyVitabile:没有,很遗憾没有。将其放入继承IDisposable的类中,然后处置该类。
PDFUtility.Document docFinal = new PDFUtility.Document();
PDFUtility.Document docToAdd = byte[] combinedFile;
List<MemoryStream> streams = new List<MemoryStream>();

try 
{
    foreach (byte[] content in fileContents)
    {
        MemoryStream fileContentStream = new MemoryStream(content);
        streams.Add(fileContentStream); //EACH INSTANCE OF A STREAM IS TRACKED
        docToAdd = new PDFUtility.Document(fileContentStream);
        docFinal.Pages.AddRange(docToAdd.Pages.CloneToArray());
    }
    using (MemoryStream stream = new MemoryStream())
    {
        docFinal.Write(stream);
        combinedFile = stream.ToArray();
    }

}
finally 
{
    streams.ForEach(s => s.Dispose()); //DISPOSE OF ALL STREAMS HERE
}