2017-09-19 112 views
-3

以下函數用於將字符串轉換爲SqlXmlSystem.Data.SqlTypes.SqlXml)。但是,它有以下運行時錯誤?少了什麼東西?MemoryStream:System.ObjectDisposedException:無法訪問處置對象

System.ObjectDisposedException:無法訪問處置的對象。

對象名稱:'在流關閉時無效嘗試調用Read。'。

System.Data.SqlTypes.SqlXml GetXml(string s) 
{ 
    using (var memoryStream = new MemoryStream()) 
    { 
     var settings = new XmlWriterSettings(); 
     settings.OmitXmlDeclaration = true; 
     settings.ConformanceLevel = ConformanceLevel.Fragment; 

     using (var xmlWriter = XmlWriter.Create(memoryStream, settings)) 
     { 
      xmlWriter.WriteString(s); 
      return new SqlXml(memoryStream); 
     } 
    } 
} 

錯誤發生在最後一行。

var range = GetXml("<Range><Column Name=\"Id\" Low=\"3397\" High=\"8999\" /></Range>"); 
cmd.Parameters.Add(new SqlParameter("@range", SqlDbType.Xml) { Value = range }); 
var result = cmd.ExecuteScalar(); 

回答

2

沒有好的Minimal, Complete, and Verifiable code example,特別是關於SqlZml類的細節,這將是不可能精確診斷您的問題。但&hellip;您正在處置memoryStream。看起來SqlXml構造函數不會立即讀取流,而是等到您嘗試實際使用SqlXml對象。由於您已經處理了傳遞給SqlXml構造函數的memoryStream對象,因此SqlXml嘗試從該流讀取時會發生異常。

不知道什麼SqlXml是或應該如何工作,我不能肯定地說,處理這個問題的正確方法是什麼。但很可能你所要做的就是停止處理memoryStream對象。即不包括using聲明。 A MemoryStream對象實際上並不需要進行處理(它不包含任何非託管資源),並且假設SqlXml寫入正確,它將獲取傳遞給它的Stream對象的所有權。所以你所需要做的就是記得稍後處理對象SqlXml,當你完成它。

如果上述內容不能解決您的問題,請通過提供更多詳細信息來改善問題,包括良好的MCVE以及關於SqlXml課程的具體內容及其工作方式。

+0

這已經是MCV示例。 'SqlXml'是系統類型。 – ca9163d9

0

在您發表的例子中,SqlXml對象消耗了memoryStream實例作爲依賴,並持有新SqlXml對象的範圍內對它的引用,但代碼到達之前,它不會用它做任何事GetXml()方法的return聲明。

GetXml()返回時using (var memoryStream = new MemoryStream())塊得到滿足,因此運行時會配置memoryStream實例。之後,SqlXml對象包含對已處理對象的引用,並且嘗試在SqlXml對象內使用該引用會導致您遇到的異常。

一個解決方案可能是使SqlXml對象實現IDisposable,所以當調用Dispose()時,它會自行配置MemoryStream。然後,您可以將呼叫打包到using區塊中:

using (SqlXml range = GetXml("...")) 
{ 
    ... 
} 
相關問題