Stream.Dispose는 항상 Stream.Close (및 Stream.Flush)를 호출합니까?
다음과 같은 경우 :
StreamWriter MySW = null;
try
{
Stream MyStream = new FileStream("asdf.txt");
MySW = new StreamWriter(MyStream);
MySW.Write("blah");
}
finally
{
if (MySW != null)
{
MySW.Flush();
MySW.Close();
MySW.Dispose();
}
}
MySW.Dispose()
Close가 제공 되더라도 그냥 호출 하고 건너 뛸 수 있습니까 ? 예상대로 작동하지 않는 스트림 구현이 있습니까 (예 : CryptoStream)?
그렇지 않은 경우 다음은 잘못된 코드입니다.
using (StreamWriter MySW = new StreamWriter(MyStream))
{
MySW.Write("Blah");
}
MySW.Dispose ()를 호출하고 Close가 제공된 경우에도 건너 뛸 수 있습니까?
예, 그게 목적입니다.
예상대로 작동하지 않는 Stream 구현이 있습니까 (예 : CryptoStream)?
객체가를 구현 IDisposable
하면 자신을 적절히 폐기 할 것이라고 가정하는 것이 안전합니다 .
그렇지 않으면 버그가 될 것입니다.
그렇지 않은 경우 다음은 잘못된 코드입니다.
아니요, 해당 코드는 .NET Framework를 구현하는 개체를 처리하는 데 권장되는 방법입니다 IDisposable
.
더 우수한 정보는 Close and Dispose-누구에게 전화해야합니까?
나는 Reflector를 사용했고 System.IO.Stream.Dispose
다음과 같은 것을 발견했습니다 .
public void Dispose()
{
this.Close();
}
Daniel Bruckner가 언급했듯이 Dispose와 Close는 사실상 동일합니다.
그러나 Stream은 삭제 / 닫힐 때 Flush ()를 호출하지 않습니다. FileStream (그리고 캐싱 메커니즘이있는 다른 Stream을 가정)은 폐기 될 때 Flush ()를 호출합니다.
Stream 또는 MemoryStream 등을 확장하는 경우 필요한 경우 삭제 / 닫을 때 Flush () 호출을 구현해야합니다.
StreamWriter.Dispose () 및 Stream.Dispose () 모두 개체가 보유한 모든 리소스를 해제합니다. 둘 다 기본 스트림을 닫습니다.
Stream.Dispose ()의 소스 코드 (이는 구현 세부 사항이므로 의존하지 마십시오) :
public void Dispose()
{
this.Close();
}
StreamWriter.Dispose () (Stream.Dispose ()와 동일) :
protected override void Dispose(bool disposing)
{
try
{
// Not relevant things
}
finally
{
if (this.Closable && (this.stream != null))
{
try
{
if (disposing)
{
this.stream.Close();
}
}
finally
{
// Not relevant things
}
}
}
}
Still, I usually implicitly close streams/streamwriters before disposing them - I think it looks cleaner.
All standard Streams (FileStream, CryptoStream) will attempt to flush when closed/disposed. I think you can rely on this for any Microsoft stream implementations.
As a result, Close/Dispose can throw an exception if the flush fails.
In fact IIRC there was a bug in the .NET 1.0 implementation of FileStream in that it would fail to release the file handle if the flush throws an exception. This was fixed in .NET 1.1 by adding a try/finally block to the Dispose(boolean) method.
For objects that need to be manually closed, every effort should be made to create the object in a using block.
//Cannot access 'stream'
using (FileStream stream = File.Open ("c:\\test.bin"))
{
//Do work on 'stream'
} // 'stream' is closed and disposed of even if there is an exception escaping this block
// Cannot access 'stream'
In this way one can never incorrectly access 'stream' out of the context of the using clause and the file is always closed.
I looked in the .net source for the Stream class, it had the following which would suggest that yes you can...
// Stream used to require that all cleanup logic went into Close(),
// which was thought up before we invented IDisposable. However, we
// need to follow the IDisposable pattern so that users can write
// sensible subclasses without needing to inspect all their base
// classes, and without worrying about version brittleness, from a
// base class switching to the Dispose pattern. We're moving
// Stream to the Dispose(bool) pattern - that's where all subclasses
// should put their cleanup starting in V2.
public virtual void Close()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose()
{
Close();
}
Stream.Close
is implemented by a call to Stream.Dispose
or vice versa - so the methods are equivalent. Stream.Close
exists just because closing a stream sounds more natural than disposing a stream.
Besides you should try to avoid explicit calls to this methods and use the using
statement instead in order to get correct exception handling for free.
'program story' 카테고리의 다른 글
Android Studio에서 Gradle '오프라인 모드'를 비활성화하는 방법은 무엇입니까? (0) | 2020.11.26 |
---|---|
PHP 7에서“선언은… 호환되어야합니다”경고가 표시되지 않습니다. (0) | 2020.11.26 |
DOM 요소는 무엇입니까? (0) | 2020.11.26 |
단어 목록을 만들기 위해 모든 공백을 줄 바꿈 / 단락 표시로 바꿉니다. (0) | 2020.11.26 |
Vim의 내용이 아닌 HTML 태그를 삭제하는 방법 (0) | 2020.11.26 |