빈 try 블록으로 try {} finally {}를 사용하는 이유는 무엇입니까?


239

나는 눈치 System.Threading.TimerBase.Dispose()방법은이 try{} finally{}블록을하지만이 try{}비어 있습니다.

try{} finally{}비어있는 상태 에서 사용할 때 어떤 가치가 try있습니까?

http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Threading&type=TimerBase

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal bool Dispose(WaitHandle notifyObject)
{
    bool status = false;
    bool bLockTaken = false;
    RuntimeHelpers.PrepareConstrainedRegions();
    try {
    }
    finally {
        do {
            if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) {
                bLockTaken = true;
                try {
                    status = DeleteTimerNative(notifyObject.SafeWaitHandle);
                }
                finally {
                    m_lock = 0;
                }
            }
            Thread.SpinWait(1);
            // yield to processor
        }
        while (!bLockTaken);
        GC.SuppressFinalize(this);
    }

    return status;
}

System.Diagnostics.Process가 라인 2144 주위뿐만 아니라 : referencesource.microsoft.com/#System/services/monitoring/...
패트릭 ARTNER

답변:


171

에서 http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/ :

이 방법은 처리를 방해하는 Thread.Abort 호출을 방지합니다. Thread.Abort의 MSDN 페이지에는 "스레드가 중단되기 전에 실행되지 않은 최종 블록이 실행됩니다"라고 말합니다. 따라서 누군가 스레드에서 중단을 호출하여 스레드가 중간에 중단 된 경우에도 처리가 완료되도록하려면 모든 코드를 finally 블록에 배치 할 수 있습니다 (대안은 "catch"블록에 코드를 작성하는 것임). “시도”가 중단에 의해 중단되기 전의 위치를 ​​결정하고 원하는 경우 거기서 계속 진행하십시오).


6
msdn.microsoft.com/en-us/library/…를 사용하지 않는 이유는 무엇 입니까?
Rob Fonseca-Ensor

15
즉, .NET 2.0까지 사용할 수 없습니다 때문에
한스 옆모습

6
RobFonseca-ENSOR @ : 때문에 Thread.BeginCriticalRegion()하지 않습니다 방지 가 취소되는 스레드를 대신하는 런타임 알려줍니다 경우 스레드가 중단되고, 다음 글로벌 상태가 손상을, 전체 응용 프로그램 도메인은 자비 살인까지입니다.
kkm

9
@HansPassant은 : BeginCriticalSection()정말 .NET 1.x에서에 없었다, 그러나 원인과 결과는 당신이 말하는 의미하는 것으로,이 없습니다 때문에 . 실제로 .NET 1.x에서는 finally블록 중단이 스레드 중단으로 인해 중단되었을 수 있습니다. 이러한 메커니즘은 다른 목적 finally으로 사용됩니다. 코드에서 중간에 중단 되는 것을 방지 BeginCriticalSection()하고 전역 상태가 위험하다는 런타임 만 선언합니다.
kkm December

개발자가 드디어 while (true)을 가지고 있다면 중단이 완료되거나 기술적으로 중단이 무기한 무시 될 수 있습니까?
Max Young

64

이것은 Thread.Abort프로세스 중단 을 막기 위한 것입니다. 이 방법에 대한 설명서 는 다음과 같이 말합니다.

스레드가 중단되기 전에 실행되지 않은 finally 블록이 실행됩니다.

오류에서 성공적으로 복구하려면 코드 자체를 정리해야합니다. C #은 C ++가 없기 때문에 - 스타일의 소멸자를, finally그리고 using블록은 그러한 정리를 보장하는 신뢰할 수있는 유일한 방법이 신뢰성있게 수행합니다. using컴파일러가 블록을 이것으로 바꾼다는 것을 기억하십시오 :

try {
    ...
}
finally {
    if(obj != null)
        ((IDisposable)obj).Dispose();
}

.NET 1.x에서 finally블록이 중단 될 가능성이있었습니다 . 이 동작은 .NET 2.0에서 변경되었습니다.

또한 빈 try블록은 컴파일러에 의해 최적화되지 않습니다.


using 블록에 대한 통찰력에 감사드립니다.
스테판

@Anton 사용하는 것이 가장 좋습니다. 그러나 조롱 목적으로 래퍼 클래스를 구현해야하고 일회용 객체가 전용 ​​클래스 변수가됩니다. 이 래퍼를 일회용으로 만들면 GC가 개인 클래스 변수의 처리를 자동으로 처리하지 않습니까?
오즈 칸

@Ozkan the GC는 자동으로 아무것도 처리하지 않습니다. 일반적으로을 호출하는 종료자를 구현해야합니다 Dispose(false);. docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…
Thorarin

@Thorarin 죄송하지만 GC가 자동으로 (최종 처리)하지 않는다고 말함으로써 잘못되었습니다.
오즈 칸
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.