2011-11-18 2 views
0

using 문은 예외를 캡처하지 않습니다.예외 캐칭.

1) 사용을 푸는하고 수동으로 구현 : 당신은 두 가지 선택이 예외를 포착하려면

void MyFunc() 
{ 
    StreamReader myReader = null; 

    try 
    { 
     myReader = new StreamReader(path); 
     //use myReader 
    } 
    catch (Exception e) 
    { 
     //do something with exception 
    } 
    finally 
    { 
     if (myReader != null) 
      myReader.Dispose(); 
    } 
} 

또는 2) 계속 사용하고, 다른 시도의 catch 블록에서 포장을

void MyFunc() 
{ 
    try 
    { 
     using (StreamReader myReader = new StreamReader(path)) 
     { 
      //use myReader 
     } 
    } 
    catch (Exception e) 
    { 
     //do something with exception 
    } 
} 

나에게 두 번째 것은 특히 흐름을 더 잘 설명하고 명시 적 선언, Null 검사 및 Dispose() 호출을 제거하기 때문에 여러 개의 using 문을 사용하는 경우 더 깔끔하게 보입니다.

그러나 실제로 중복되는 추가 캐치 오버 헤드로 인해 잘못 생각합니다.

표준 연습이란 무엇입니까?

+3

두 번째 방법은 어떻게 중복됩니까? – Tim

+1

특히 poll_ish 인 이유로 SO에 적합하지는 않지만, 후자가 반전 된 것을 선호합니다 (내부에서 try/catch). 그것은 나 자신을 수동으로 처리하는 것보다 일사량이 약간 더 많아 질 수 있다는 것을 전혀 신경 쓰지 않습니다. 그것은 나를 위해 일하는 것이 적어서, 처음부터'사용하기 '의 요점입니다. –

+0

@ 팀 : IL이 두 가지 예외 처리 지점을 설정해야한다고 생각했습니다. 하나는 바깥 쪽 try를위한 것이고, 다른 하나는 암시 적 try를 사용하는 것입니다. – GazTheDestroyer

답변

6

예외 처리 구조의 오버 헤드는 메타 데이터 일뿐입니다. 예외가 발생하지 않으면 런타임 성능 오버 헤드가 없습니다. 예외 처리 절을 시작/종료하는 다른 런타임과 달리 .net에서는 무료입니다. 예외가 발생하면 런타임은 메타 데이터와 현재 명령어 포인터를 사용하여 실행할 처리 절을 찾습니다.

나는 두 번째 것을 선호한다. 리소스를 해제하고 예외를 처리하는 것은 별도의 개념이므로 코드에서 분리되는 것은 자연스러운 일입니다.

+0

예외가 없을 때 오버 헤드가 발생하지 않는 예외 처리에 대한 문서가 있습니까? 내 동료가 항상 그렇다고 주장한다 –

+0

+1 Marc의 [Exceptions and Performance] (http://www.yoda.arachsys.com/csharp/exceptions.html)에서이 링크를 클릭하면 " 무료 "(예외가 * 던져진 시간을 계산해야합니까?? -),하지만 ... –

0

매우 구체적인 요구 사항이있을 때까지 메소드에서 "try-catch"를 피하십시오. 예를 들어 응용 프로그램이 시작되기 전에 데이터베이스 연결을 확인하는 것과 같습니다.

예외 처리는 .Net 응용 프로그램에서 매우 비용이 많이 드는 일이됩니다.

그럼에도 불구하고 두 번째 옵션이 표시되면 더 좋습니다. 다시 이것은 예외 처리의 매우 요구 사항에 주관적입니다.

일반적인 오류 처리 (예 : 로깅 또는 오류 메일 보내기)의 경우 Global.asax를 사용하십시오. 또는 최소한 Page_Error 이벤트로 제한하십시오.

0

또 다른 패턴을 알고 있어야합니다 - 객체가 다른 객체의 소유권 걸릴 것 생성되는 경우에 특히 유용합니다 (I 일반적으로 코드 vb.net을, 그래서 어떤 C#을 실수를 용서)

 
class MyDisposableClass 
{ 
    SomeDisposableThing myThing; 

    MyDisposableClass() // Constructor 
    { 
    bool ok = false; 

    try 
    { 
     myThing = new SomeDisposableThing(); 
     ... do some other stuff 
     ok = true; 
    } 
    finally 
    { 
     if (!ok) 
     { 
     zap(ref myThing); 
     } 
    } 
    } 
    static void zap<T>(ref T thing) where T:IDisposable,class 
    { 
    T oldValue = System.Threading.Interlocked.Exchange(thing, null); 
    if (oldValue != null) 
     oldValue.Dispose(); 
    } 
} 

주를이 누군가가 예외없이 아무 것도하지 않으면 변경하지 않고 예외를 잡을 수 있다면 예외를 잡아 내고 다시 올리는 것이 좋습니다.