[英]Disposing of object multiple times
我有以下代碼,它使用流來打開和修改Open XML文檔,然后保存該流的新二進制表示:
MemoryStream stream = null;
try
{
stream = new MemoryStream();
stream.Write(this.GetBinaryRepresentation(), 0, this.GetBinaryRepresentation().Length);
using (WordprocessingDocument document = WordprocessingDocument.Open(stream, true))
{
OfficeDocument.ModifyDocument(document);
this.SetBinaryRepresentation(stream.ToArray());
stream = null;
}
}
finally
{
if (stream != null)
{
stream.Dispose();
}
}
我最初使用了兩個使用塊(一個用於MemoryStream,第二個用於WordprocessingDocument),但收到警告CA2202:“對象'流'可以在方法中多次處理...”根據MSDN文章 ,我修改了上面的代碼(將外部使用轉換為試用),但我仍然收到此警告。
我不確定如何構造此方法以確保在流上只調用一次Dispose。 我不想簡單地抑制此警告,因為MSDN文章聲明您不應該依賴Dispose多次安全地調用。
如果在將流設置為空之前在使用塊中拋出異常,則流仍可被丟棄兩次。 嘗試這個:
MemoryStream stream = null;
MemoryStream streamToDispose = null;
try
{
streamToDispose = stream = new MemoryStream();
stream.Write(this.GetBinaryRepresentation(), 0, this.GetBinaryRepresentation().Length);
using (WordprocessingDocument document = WordprocessingDocument.Open(stream, true))
{
streamToDispose = null;
OfficeDocument.ModifyDocument(document);
this.SetBinaryRepresentation(stream.ToArray());
}
}
finally
{
if (streamToDispose != null)
{
streamToDispose.Dispose();
}
}
MSDN文章中的示例不適合您的原因是它們在進入using塊時將流設置為null,而您使用using塊中的流並將流設置為null。 如果在stream = null
語句之前拋出異常,則在退出using塊時將丟棄stream
,然后在finally塊中再次處理。
不幸的是,由於您需要在document
更新之后訪問您的流,我沒有看到一種干凈的方法來使用他們在您的using語句中設置stream = null
的示例來避免多次Dispose()
調用。 另一種方法是你可以在try塊之外聲明stream
和document
,然后在finally中清除它們,如下所示:
MemoryStream stream = null;
WordprocessingDocument document = null;
try
{
stream = new MemoryStream();
stream.Write(this.GetBinaryRepresentation(), 0, this.GetBinaryRepresentation().Length);
document = WordprocessingDocument.Open(stream, true));
OfficeDocument.ModifyDocument(document);
this.SetBinaryRepresentation(stream.ToArray());
}
finally
{
if( document != null)
{
document.Dispose();
}
// Catch the case where an error occurred before document was defined.
else
{
stream.Dispose();
}
}
using語句處理對象 - 所以基本上你調用dispose兩次
當您的代碼在WordProcessingDocument
周圍離開使用塊時,它將調用dispose。
using (WordprocessingDocument document = WordprocessingDocument.Open(stream, true))
由於WordProcessingDocument
需要的實例stream
在其構造,它會調用該流實例處理時WordProcessingDocument.Dispose
被調用。 然后輸入您調用stream.Dispose()
的finally塊 - 您現在已在流實例上調用兩次Dispose()。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.