다음 코드가 있습니다.
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
이 dispose()
메서드는 using
문 중괄호 끝에서 호출됩니다 }
. 나는 이후 return
의 끝나기 전에 using
문, 의지 MemoryStream
객체가 제대로 배치 할 수? 여기서 무슨 일이 일어나나요?
답변
네, Dispose
부릅니다. using
블록을 떠나는 데 걸린 수단에 관계없이 실행이 블록 범위를 벗어나는 즉시 호출됩니다 return
.
@Noldorin 올바르게 사용하여 지적 하듯이 using
코드 블록을 컴파일 도착 try
/ finally
과 Dispose
에서 호출되는 finally
블록. 예를 들어 다음 코드 :
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
효과적으로 :
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
따라서 블록이 실행을 마친 finally
후에 실행이 보장 되기 때문에 try
실행 경로에 Dispose
관계없이 무엇이든지 호출이 보장됩니다.
자세한 내용은 이 MSDN 문서를 참조하십시오 .
부록 : 추가
할 약간의주의 사항 : Dispose
은 호출이 보장 되기 때문에 Dispose
구현할 때 예외가 발생하지 않도록하는 것이 거의 항상 좋은 생각 IDisposable
입니다. 불행하게도, 핵심 라이브러리의 일부 클래스가 어떻게 특정 상황에 던져 Dispose
내가 당신을 찾고 있어요, WCF 서비스 참조 / 클라이언트 프록시 -라고는! -그리고 그럴 때 Dispose
예외 스택 해제 중에 호출 된 경우 원래 예외를 추적하는 것이 매우 어려울 수 있습니다 . 원래 예외가 Dispose
호출에 의해 생성 된 새 예외에 찬성하여 삼키기 때문입니다 . 그것은 미친 듯이 실망 스러울 수 있습니다. 아니면 그게 실망 스럽습니까? 둘 중 하나. 둘 다.
답변
using
문은 try ... finally
블록 과 똑같이 동작 하므로 항상 모든 코드 종료 경로에서 실행됩니다. 그러나 나는 그들이 finally
블록이 호출되지 않는 매우 드문 상황에 처해 있다고 믿습니다 . 내가 기억할 수있는 한 가지 예는 백그라운드 스레드가 활성화 된 동안 포 그라운드 스레드가 종료되는 경우입니다. GC를 제외한 모든 스레드가 일시 중지되어 finally
블록이 실행되지 않습니다.
명백한 편집 : IDisposable 개체를 처리 할 수있는 논리를 제외하고는 동일하게 동작합니다.
보너스 내용 : 스택 가능 (유형이 다른 경우) :
using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{
}
또한 쉼표로 구분 (유형이 동일한 경우) :
using (SqlCommand comm = new SqlCommand("", conn),
SqlCommand comm2 = new SqlCommand("", conn))
{
}
답변
MemoryStream 객체는 적절하게 삭제되므로 걱정할 필요가 없습니다.
답변
이랑 using
문 개체 관계없이 완료 경로 처리한다.
추가 읽기 …
답변
컴파일 한 후 리플렉터에서 코드를 살펴보십시오. 컴파일러가 코드를 리팩토링하여 dispose가 스트림에서 호출되도록합니다.