Sha*_*hen 9 .net c# dispose memorystream
以下代码用于拼接现有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();
}
Run Code Online (Sandbox Code Playgroud)
这段代码的明显问题是这个命令:
MemoryStream fileContentStream = new MemoryStream(content);
Run Code Online (Sandbox Code Playgroud)
内存流fileContentStream没有被处理掉,可能(我相信)保持资源的时间超过了所需的时间.
显而易见的解决方案是将MemoryStream的创建包装在一个using块中.代码将如下所示:
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();
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中使用using块导致代码在此行上失败(因为之前已经处理了流):
docFinal.Write(stream);
Run Code Online (Sandbox Code Playgroud)
一种可能的解决方案是跟踪所有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
Run Code Online (Sandbox Code Playgroud)
上面的代码有效.我只是推迟Dispose直到最终文件被写出来之后.
但是,这似乎不是"最佳"解决方案.有没有办法实现使用块(从而保证对象被妥善处理?
using块不仅仅是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;
}
}
Run Code Online (Sandbox Code Playgroud)
案例二:
// 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.
}
Run Code Online (Sandbox Code Playgroud)
有了这些知识,您可以修改第三个解决方案以使用finally块来确保MemoryStream始终清理对象.
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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1371 次 |
| 最近记录: |