2011-11-11 1 views
25

최근 추가 코드 분석 규칙을 사용하도록 설정했습니다. 놀랍게도 나는 항상 최고의 연습으로 생각하고 있었던 곳에서 위반을 보았습니다. 나는이 같은 두 using 문을 걸었습니다 두 개의 중첩 일회용있는 경우 :중첩 사용 문 및 Microsoft 코드 분석

using (StringReader strReader = new StringReader(xmlString)) 
    using (XmlReader xmlReader = XmlReader.Create(strReader)) 
    { 
     result.ReadXml(xmlReader); 
    } 

이것은 또한 높은 평가 Q &에 상태를 다음 내가 할 Nested using statements in C#

위반에 해당 :

Warning 18 CA2202 : Microsoft.Usage : Object 'strReader' can be disposed more 
than once in method '????'. To avoid generating a System.ObjectDisposedException 
you should not call Dispose more than one time on an object.: Lines: ?? 

내가 한 것은 직관적 인 시도와 오류였습니다. 바깥 쪽 스트림이 닫혀도 내부 코드를 처리 할 것이라고 생각 했으므로 다음과 같이 코드를 빠르게 수정했습니다.

using (XmlReader xmlReader = XmlReader.Create(new StringReader(xmlString))) 
    { 
     result.ReadXml(xmlReader); 
    } 

Hura! 경고가 사라졌습니다. 하지만, 타다! 새로운 하나가 발생했습니다 : CA2202과 정확히 놀랍게도 (모든 좋은 프로그래머처럼) 아주 마지막 단계로

{ 
     StringReader strReader = null; 
     try 
     { 
      strReader = new StringReader(xmlString); 
      using (XmlReader xmlReader = XmlReader.Create(strReader)) 
      { 
       strReader = null; 
       result.ReadXml(xmlReader); 
      } 
     } 
     finally 
     { 
      if (strReader != null) strReader.Dispose(); 
     } 
    } 

나는 보았다 도움말 페이지로 :

Warning 18 CA2000 : Microsoft.Reliability : In method '????????', object 
'new StringReader(xmlString)' is not disposed along all exception paths. Call 
System.IDisposable.Dispose on object 'new StringReader(xmlString)' before all 
references to it are out of scope. 

가 그럼 난 매우 추한 해결책을 발견 마지막 UGLY 솔루션이 문제를 해결하기 위해 제안 되었습니까?

마침내 {}을 (를) 사용하면 마침내 코드가 혼잡 해집니다. 나를 위해 더 많이 읽을 수있는 중첩 된 있습니다.

질문 : 작업을 수행하는 더 좋은 방법이 있습니까? 직관적으로 이해할 수있는 솔루션을 찾고 있습니다. 이 마지막 스 니펫을 볼 모든 사람은 일어나는 일에 대한 골동품이 될 것입니다.

미리 답변 해 주셔서 감사합니다.

+0

P.S. 아마도 MetaStackoverflow에 속해있을 것입니다. 사실, 그 질문은 이미 물어 보았을 것입니다.(XmlReader를 XmlReader를 XmlReader.Create = (strReader))를 사용하여 I 시도하는 방법도 다음 코드 '사용 (StringReader를 strReader = StringReader를 새로운 (xmlString을)) 바이 –

+0

{ strReader = NULL; result.ReadXml (xmlReader); } 오류가 발생합니다. '변수 사용'이기 때문에 'strReader'에 할당 할 수 없습니다. –

답변

21

중첩 된 사용으로 인해 문제가 발생하지 않았습니다. 그들은 잘되고 일반적으로 권장합니다. 여기서 문제는 을 CloseInput == true으로 전달하면 을 처리하지만 CA2202 규칙은 코드가 해당 분기로 내려 가지 않을만큼 똑똑하지 않다는 것입니다. 중첩 된 사용을 유지하고 CA2202 위반을 거짓 긍정으로 억제하십시오.

당신이 가독성 및/또는 유지 보수성을 향상하기 위해 코드에 명시 할 경우, falseXmlReaderSettingsCloseInput 설정을 사용하지만, 그 기본 값이므로이 꼭 필요한 것은이고, 수 분명하다, 규칙을 만족시키지 않을 것이다.

BTW에는 다양한 스트림 및 판독기 유형에 대한 유사한 CA2202 문제 시나리오가 있습니다. 유감스럽게도, 이것들은 모두 같은 것은 아니기 때문에 문제의 원인이되는 유형에 따라 최상의 사례 처리가 다를 수 있습니다.

+0

'xmlReaderSettings.CloseInput = false'는 규칙을 만족하지 않습니다. 진압은이 문제를 해결하는 유일한 방법 일뿐입니다. 'Dispose'구현에서 이중 처리를 허용하는 것이 일반적으로 좋은 생각 인 것 같습니다. 따라서 'XmlReader'와 같은 일부 사용자는 자동으로 처리하고 다른 사용자가 클래스를 'using'문으로 묶으면 BOOM을 만듭니다! 설명해 주셔서 감사합니다. 수락 됨! –

+3

CloseInput을 false로 설정하면 규칙을 만족시키지 않는다는 것이 아니라 가독성 및/또는 유지 관리 성을 향상시키기 위해 코드에서 명시 적으로 사용하고자 할 수도 있습니다. 다중 처리를 허용하는 경우에는 해당 FxCop 규칙이 없더라도 .NET 디자인 지침이 있습니다. –

0

최근에 비슷한 문제가 있었지만 serializer를 사용하는 경우에는 stringWriter를 null로 바로 설정할 수 없어 적응해야했습니다. 이 대안은 모든 CA 경고를 피합니다.

StringWriter stringWriter = null; 
XmlWriter xmlWriter = null; 
string serializedValue = null; 

try 
{ 
    XmlSerializer xmlserializer = new XmlSerializer(typeof(T)); 
    stringWriter = new StringWriter(); 

    xmlWriter = XmlWriter.Create(stringWriter); 
    xmlserializer.Serialize(xmlWriter, value); 
    xmlWriter.Flush(); 
    serializedValue = stringWriter.ToString(); 
} 
finally 
{ 
    if (xmlWriter != null) //Both objects need disposed 
    { 
     xmlWriter.Dispose(); //stringWriter will dispose automatically too 
    } 
    else if (stringWriter != null) //XmlWriter failed to create 
    { 
     stringWriter.Dispose(); //just dispose stringWriter 
    } 
}