Windows Forms 응용 프로그램에서 예외 처리를위한 모범 사례?


118

현재 첫 번째 Windows Forms 응용 프로그램을 작성하는 중입니다. 지금까지 몇 권의 C # 책을 읽었으므로 C #이 예외를 처리해야하는 언어 기능을 비교적 잘 이해하고 있습니다. 그것들은 모두 매우 이론적이지만 아직 내가 얻지 못한 것은 내 응용 프로그램에서 기본 개념을 좋은 예외 처리 모델로 변환하는 방법에 대한 느낌입니다.

주제에 대해 지혜의 진주를 공유하고 싶은 사람이 있습니까? 저와 같은 초보자들이 저지르는 일반적인 실수와 제 애플리케이션을 더 안정적이고 견고하게 만드는 방식으로 예외를 처리하는 것에 대한 일반적인 조언을 게시하십시오.

내가 현재 해결하려는 주요 사항은 다음과 같습니다.

  • 언제 예외를 다시 던져야합니까?
  • 어떤 종류의 중앙 오류 처리 메커니즘을 갖춰야합니까?
  • throw 될 수있는 예외 처리는 디스크에 파일이 있는지 여부와 같은 선제 적 테스트에 비해 성능 저하가 있습니까?
  • 모든 실행 코드를 try-catch-finally 블록으로 묶어야합니까?
  • 빈 catch 블록이 허용되는 경우가 있습니까?

모든 조언을 감사하게 받았습니다!

답변:


79

조금 더 ...

중앙 집중식 예외 처리 정책이 있어야합니다. 이것은 Main()try / catch 로 래핑 하는 것처럼 간단 할 수 있으며 사용자에게 우아한 오류 메시지가 표시되면서 빠르게 실패합니다. 이것은 "마지막 수단"예외 처리기입니다.

선제 적 검사는 가능하면 항상 정확하지만 항상 완벽한 것은 아닙니다. 예를 들어 파일의 존재를 확인하는 코드와 파일을 여는 다음 줄 사이에서 파일이 삭제되었거나 다른 문제로 인해 액세스가 방해를받을 수 있습니다. 그 세계에서 여전히 try / catch / finally가 필요합니다. 선점 검사와 try / catch / finally를 모두 적절하게 사용합니다.

예외를 절대로 "삼키지"마십시오. 단, 가장 잘 문서화되어있는 경우를 제외하고는 예외가 발생할 수 있다는 확신이 있습니다. 이것은 거의 사실이 아닙니다. (그렇다면 특정 예외 클래스 만 삼키고 있는지 확인하십시오 . 절대 삼키지 마십시오 System.Exception.)

앱에서 사용하는 라이브러리를 빌드 할 때 예외를 삼키지 말고 예외가 발생하는 것을 두려워하지 마십시오. 추가 할 유용한 것이 없으면 다시 던지지 마십시오. 절대로 (C #에서) 다음을 수행하지 마십시오.

throw ex;

호출 스택을 지울 것입니다. 다시 던져야하는 경우 (엔터프라이즈 라이브러리의 예외 처리 블록을 사용할 때와 같이 가끔 필요함) 다음을 사용하십시오.

throw;

하루가 끝나면 실행중인 응용 프로그램에서 발생하는 대부분의 예외가 어딘가에 노출되어야합니다. 최종 사용자에게 노출되어서는 안되며 (종종 독점적이거나 중요한 데이터가 포함되어 있기 때문에) 일반적으로 관리자에게 예외를 알리는 로그와 함께 기록됩니다. 사용자에게 참조 번호가있는 일반 대화 상자가 표시되어 작업을 단순화 할 수 있습니다.

.NET의 예외 처리는 과학보다 예술입니다. 모든 사람이 즐겨 찾기를 여기에서 공유 할 수 있습니다. 다음은 1 일차부터 .NET을 사용하여 배운 몇 가지 팁에 불과합니다.이 기술은 한 번 이상 제 베이컨을 구해준 기술입니다. 귀하의 마일리지가 다를 수 있습니다.


1
예외가 발생하면 호출자가 예외가 작업이 실패했음을 나타내는 지 여부를 어떻게 알 수 있지만 시스템은 근본적으로 정상입니다 (예 : 사용자가 손상된 문서 파일을 열려고 시도했습니다. 파일이로드되지 않지만 모든 것이 그렇지 않으면 CPU가 불타고 있고 가능한 한 빨리 출구로 향해야한다는 것을 나타내는 지 여부? ArgumentException과 같은 것은 발생하는 상황에 따라 둘 중 하나를 나타낼 수 있습니다.
supercat

2
@supercat ApplicationException응용 프로그램이 합리적으로 구별하고 처리 할 수 ​​있어야하는 실패 사례 에 대한 특정 하위 클래스를 작성합니다 .
Matt Enright

@Matt Enright : 물론 자신의 예외를 잡을 수는 있지만 예외를 던지는 모듈이 실패로 암시 된 것 이상으로 외부 상태의 손상을 나타내는 지 여부를 나타내는 규칙과 원격으로 유사한 것을 알지 못합니다. 이상적으로는 SuperDocument.CreateFromFile ()과 같은 메서드가 성공하거나 CleanFailure 예외를 발생 시키거나 SomethingReallyBadHappenedException을 발생시킵니다. 불행히도 예외를 발생시킬 수있는 모든 것을 자체 catch 블록 내에서 래핑하지 않는 한 InvalidOperationException ...인지 알 수있는 방법이 없습니다.
supercat

@Matt Enright : ... CleanFailureException 또는 SomethingReallyBadHappenedException으로 래핑되어야합니다. 그리고 모든 것을 개별 try-catch 블록으로 래핑하면 처음에 예외를 갖는 모든 목적을 무력화 할 수 있습니다.
supercat

2
부정확 한 예외 유형으로 실패 모드를 숨기는 것은 좋지 않은 라이브러리 디자인이라고 생각합니다. 응용 프로그램이 각 경우에 다르게 응답해야하므로 실제로 의미하는 것이 IOException 또는 InvalidDataException 인 경우 FileNotFoundException을 throw하지 마십시오. StackOverflowException 또는 OutOfMemoryException과 같은 것은 응용 프로그램에서 합리적으로 처리 할 수 ​​없으므로 잘 작동하는 응용 프로그램에는 어쨌든 중앙 집중식 "마지막 수단"처리기가 ​​있으므로 버블 링 만 허용하면됩니다.
Matt Enright 2011-07-28

63

여기에 훌륭한 코드 CodeProject 기사가 있습니다 . 다음은 몇 가지 주요 사항입니다.

  • 최악의 계획 *
  • 일찍 확인
  • 외부 데이터를 신뢰하지 마십시오
  • 신뢰할 수있는 유일한 장치는 비디오, 마우스 및 키보드입니다.
  • 쓰기도 실패 할 수 있습니다.
  • 안전하게 코딩
  • new Exception ()을 던지지 마십시오.
  • 메시지 필드에 중요한 예외 정보를 입력하지 마십시오.
  • 스레드 당 단일 캐치 (예외 예)를 넣으십시오.
  • 잡힌 일반 예외를 게시해야합니다.
  • Log Exception.ToString (); Exception.Message 만 기록하지 마십시오!
  • 스레드 당 두 번 이상 (예외)를 포착하지 마십시오.
  • 예외를 삼키지 마십시오
  • 정리 코드는 finally 블록에 넣어야합니다.
  • 어디서나 "사용"사용
  • 오류 조건에서 특수 값을 반환하지 마십시오.
  • 리소스가 없음을 나타 내기 위해 예외를 사용하지 마십시오.
  • 메서드에서 정보를 반환하는 수단으로 예외 처리를 사용하지 마십시오.
  • 무시해서는 안되는 오류에 예외 사용
  • 예외를 다시 던질 때 스택 추적을 지우지 마십시오.
  • 의미 값을 추가하지 않고 예외 변경 방지
  • 예외는 [Serializable]로 표시되어야합니다.
  • 의심 스러우면 어설 션하지 말고 예외를 던져라
  • 각 예외 클래스에는 최소한 세 개의 원래 생성자가 있어야합니다.
  • AppDomain.UnhandledException 이벤트를 사용할 때주의하십시오.
  • 바퀴를 재발 명하지 마십시오
  • 구조화되지 않은 오류 처리 (VB.Net)를 사용하지 마십시오.

3
이 점에 대해 좀 더 설명해 주시겠습니까? "자원이 없음을 나타 내기 위해 예외를 사용하지 마십시오."그 이유를 잘 모르겠습니다. 또한 언급 :이 답변은 "왜"를 전혀 설명하지 않습니다. 나는 이것이 5 살이라는 것을 알고 있지만 여전히 나를 약간
괴롭힌다

참조 된 기사에 대한 링크가 만료되었습니다. Code Project는 기사가 여기 로 옮겨 졌을 수 있다고 제안합니다 .
DavidRR

15

Windows Forms에는 자체 예외 처리 메커니즘이 있습니다. 양식의 단추를 클릭하고 해당 처리기가 처리기에서 포착되지 않은 예외를 throw하면 Windows Forms는 자체 처리되지 않은 예외 대화 상자를 표시합니다.

처리되지 않은 예외 대화 상자가 표시되는 것을 방지하고 로깅 및 / 또는 자체 오류 대화 상자를 제공하기 위해 이러한 예외를 포착하려면 Main () 메서드에서 Application.Run ()을 호출하기 전에 Application.ThreadException 이벤트에 연결할 수 있습니다.


이 제안에 감사드립니다. 너무 늦게 배웠습니다. 방금 linqpad에서 확인했으며 예상대로 작동합니다. 대리자는 다음과 같습니다. void Form1_UIThreadException (object sender, ThreadExceptionEventArgs t)이 주제에 대한 또 다른 좋은 소스는 richnewman.wordpress.com/2007/입니다. 04 / 08 /… 전반적인 처리되지 않은 예외 처리 : AppDomain.UnhandledException 이벤트는 비 메인 UI 스레드에서 throw 된 처리되지 않은 예외에 대한 것입니다.
zhaorufei

14

지금까지 여기에 게시 된 모든 조언은 훌륭하고주의 할 가치가 있습니다.

내가 확장하고 싶은 한 가지는 "디스크에 파일이 존재하는지 여부와 같은 사전 테스트에 비해 throw 될 수있는 예외 처리가 성능 저하를 가져 오는가?"라는 질문입니다.

어림짐작은 "try / catch 블록은 비싸다"는 것입니다. 그것은 사실이 아닙니다. 노력하는 것은 비싸지 않습니다. 시스템이 Exception 객체를 생성하고 스택 추적과 함께로드해야하는 캐치입니다. 비용이 많이 듭니다. 예외가 예외 인 경우가 많아서 try / catch 블록에 코드를 래핑해도 무방합니다.

예를 들어 사전을 채우는 경우 다음과 같습니다.

try
{
   dict.Add(key, value);
}
catch(KeyException)
{
}

다음을 수행하는 것보다 더 빠릅니다.

if (!dict.ContainsKey(key))
{
   dict.Add(key, value);
}

추가하는 모든 단일 항목에 대해 예외는 중복 키를 추가 할 때만 발생하기 때문입니다. (LINQ 집계 쿼리가이 작업을 수행합니다.)

당신이 준 예에서는 거의 생각하지 않고 try / catch를 사용합니다. 첫째, 파일을 확인할 때 파일이 존재한다고해서 열 때 파일이 존재한다는 의미는 아니므로 어쨌든 예외를 처리해야합니다.

둘째, 더 중요하게 생각합니다. a) 프로세스가 수천 개의 파일을 열고 b) 열려고하는 파일이 존재하지 않을 확률이 사소하게 낮지 않고 예외를 생성 할 때 성능 저하가 발생하지 않는 한 다시는 알아 차릴 것입니다. 일반적으로 프로그램은 파일을 열려고 할 때 하나의 파일 만 열려고합니다. 가장 빠른 코드를 작성하는 것보다 안전한 코드를 작성하는 것이 거의 확실하게 더 나은 경우입니다.


3
dict의 경우, 당신은 그냥 할 수 있습니다 : dict[key] = value빠르지는 않더라도 빠를 것입니다 ..
nawfal

9

내가 따르는 몇 가지 지침은 다음과 같습니다.

  1. Fail-Fast : 이것은 예외 생성 지침에 가깝습니다. 모든 가정과 함수에 들어가는 모든 매개 변수에 대해 올바른 데이터로 시작하고 가정이 올바른지 확인합니다. '제작이 정확합니다. 일반적인 검사에는 null이 아닌 인수, 예상 범위의 인수 등이 포함됩니다.

  2. 다시 던질 때 스택 추적 유지-이것은 단순히 new Exception ()을 throw하는 대신 다시 던질 때 throw를 사용하는 것으로 변환됩니다. 또는 더 많은 정보를 추가 할 수 있다고 생각되면 원래 예외를 내부 예외로 래핑하십시오. 그러나 예외를 포착하여 기록하는 경우에는 반드시 throw를 사용하십시오.

  3. 처리 할 수없는 예외를 포착하지 마십시오. OutOfMemoryException과 같은 일에 대해 걱정하지 마십시오. 이러한 예외가 발생하면 어쨌든 많은 일을 할 수 없습니다.

  4. 전역 예외 처리기를 후크하고 가능한 한 많은 정보를 기록하십시오. winforms의 경우 appdomain 및 스레드 처리되지 않은 예외 이벤트를 모두 연결합니다.

  5. 성능은 코드를 분석 한 후 성능 병목 현상을 유발하는 것으로 확인 된 경우에만 고려되어야하며 기본적으로 가독성과 디자인을 위해 최적화됩니다. 그래서 파일 존재 확인에 대한 원래 질문에 대해서는, 파일이 존재하지 않는 것에 대해 무언가를 할 수 있다면 예, 그렇지 않으면 확인을 수행하십시오. 파일이없는 경우 예외를 던지는 것뿐입니다. 거기가 아니라면 요점이 보이지 않습니다.

  6. 빈 catch 블록이 필요한 경우가 분명히 있습니다. 여러 릴리스에서 발전한 코드베이스에 대해 작업하지 않았다고 말하는 사람들이 있습니다. 하지만 실제로 필요한지 확인하기 위해 주석을 달고 검토해야합니다. 가장 일반적인 예는 ParseInt ()를 사용하는 대신 try / catch를 사용하여 문자열을 정수로 변환하는 개발자입니다.

  7. 코드 호출자가 오류 조건을 처리 할 수있을 것으로 예상되는 경우 예상치 못한 상황을 자세히 설명하고 관련 정보를 제공하는 사용자 지정 예외를 만듭니다. 그렇지 않으면 가능한 한 많이 내장 된 예외 유형을 고수하십시오.


appdomain과 스레드 처리되지 않은 예외 핸들러를 모두 후크하는 데 사용되는 것은 무엇입니까? Appdomain.UnhandledException을 사용하는 경우 모든 것을 잡아내는 가장 일반적인 것이 아닙니까?
Quagmire 2011

Application.ThreadException"스레드 처리되지 않은 예외"이벤트를 참조 할 때 이벤트를 처리한다는 뜻 입니까?
Jeff B

4

나는 특정 상황에서 처리가 의미하는 바가 무엇이든 내가 처리하려고 의도하지 않은 것을 잡지 않는 철학을 좋아합니다.

나는 다음과 같은 코드를 볼 때 싫어한다.

try
{
   // some stuff is done here
}
catch
{
}

나는 이것을 때때로 보았고 누군가가 예외를 '먹을'때 문제를 찾는 것은 매우 어렵습니다. 내가 가진 동료가이 일을했고 결국 문제의 꾸준한 흐름에 기여하는 경향이 있습니다.

예외에 대한 응답으로 내 특정 클래스가 수행해야 할 작업이 있지만 문제가 발생한 방법을 호출하여 문제를 해결해야하는 경우 다시 던집니다.

코드는 사전에 작성해야하며 예외는 조건 테스트를 피하기위한 것이 아니라 예외적 인 상황을위한 것이어야한다고 생각합니다.


@Kiquenet 죄송합니다 조금 명확하지 않았습니다. 내가 의미하는 바 : 그런 빈 캐치를하지 말고 Dispatcher.UnhandledException에 핸들러를 추가하고 적어도 로그를 추가하여 빵 부스러기없이 먹지 않도록합니다. :) 그러나 조용한 구성 요소가 필요하지 않으면 예외를 항상 포함해야합니다. 당신의 디자인에. 던져야 할 때 던져 버리고 인터페이스 / API / 모든 클래스에 대한 명확한 계약을 작성하십시오.
LuckyLikey

4

나가는 중이지만 예외 처리를 사용할 위치에 대해 간략하게 설명하겠습니다. 내가 돌아올 때 다른 요점을 해결하려고 시도 할 것입니다 :)

  1. 알려진 모든 오류 조건을 명시 적으로 확인 *
  2. 모든 경우를 처리 할 수 ​​있는지 확실하지 않은 경우 코드 주위에 try / catch를 추가합니다.
  3. 호출중인 .NET 인터페이스에서 예외가 발생하는 경우 코드 주위에 try / catch를 추가합니다.
  4. 복잡성 임계 값을 초과하는 경우 코드 주위에 try / catch 추가
  5. 온 전성 검사를 위해 코드 주위에 try / catch를 추가하십시오. 당신은 이것이 절대 일어나지 않아야한다고 주장합니다.
  6. 일반적으로 반환 코드 대신 예외를 사용하지 않습니다. .NET에서는 괜찮지 만 나는 아닙니다. 이 규칙에는 예외가 있지만 작업중인 응용 프로그램의 아키텍처에 따라 다릅니다.

*합리적으로. 우주 광선이 데이터에 부딪혀서 몇 비트가 뒤집혀 지는지 확인할 필요가 없습니다. "합리적인"것이 무엇인지 이해하는 것은 엔지니어에게 습득 한 기술입니다. 수량화하기는 어렵지만 직관하기는 쉽습니다. 즉, 특정 경우에 try / catch를 사용하는 이유를 쉽게 설명 할 수 있지만 다른 사람에게 이와 동일한 지식을 주입하기가 어렵습니다.

필자는 예외 기반 아키텍처에서 멀어지는 경향이 있습니다. try / catch에는 성능 저하가 없습니다. 예외가 발생하면 히트가 발생하고 코드가이를 처리하기 전에 여러 수준의 호출 스택을 걸어야 할 수 있습니다.


4

고수하려는 황금률은 가능한 한 소스에 가깝게 예외를 처리하는 것입니다.

예외를 다시 던져야한다면 FileNotFoundException을 다시 던져도 별 도움이되지 않지만 ConfigurationFileNotFoundException을 던져 버리면 체인의 어딘가에서 캡처되고 작동 할 수 있습니다.

내가 따르려고하는 또 다른 규칙은 try / catch를 프로그램 흐름의 한 형태로 사용하지 않는 것이므로 파일 / 연결을 확인하고 개체를 사용하기 전에 개체가 시작되었는지 확인합니다. Try / catch는 제어 할 수없는 예외를위한 것이어야합니다.

빈 catch 블록의 경우 예외를 생성 한 코드에서 중요한 작업을 수행하는 경우 최소한 예외를 다시 발생시켜야합니다. 예외를 발생시킨 코드의 결과가 실행되지 않는 경우 왜 처음에 작성 했습니까?


이 "황금 규칙"은 기껏해야 임의적입니다.
Evan Harper

3

ThreadException 이벤트를 트랩 할 수 있습니다.

  1. 솔루션 탐색기에서 Windows 응용 프로그램 프로젝트를 선택합니다.

  2. 생성 된 Program.cs 파일을 두 번 클릭하여 엽니 다.

  3. 코드 파일 맨 위에 다음 코드 줄을 추가합니다.

    using System.Threading;
  4. Main () 메서드에서 메서드의 첫 번째 줄로 다음을 추가합니다.

    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
  5. Main () 메서드 아래에 다음을 추가합니다.

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        // Do logging or whatever here
        Application.Exit();
    }
  6. 이벤트 처리기 내에서 처리되지 않은 예외를 처리하는 코드를 추가합니다. 응용 프로그램의 다른 곳에서 처리되지 않는 모든 예외는 위 코드에 의해 처리됩니다. 가장 일반적으로이 코드는 오류를 기록하고 사용자에게 메시지를 표시해야합니다.

참조 : https://blogs.msmvps.com/deborahk/global-exception-handler-winforms/


죄송 @Kiquenet, 나도 몰라 VB에 대한
오 미드-RH

2

예외는 비싸지 만 필요합니다. try catch로 모든 것을 래핑 할 필요는 없지만 결국 예외가 항상 catch되도록해야합니다. 그것의 대부분은 당신의 디자인에 달려 있습니다.

예외를 높이는 것이 똑같이 가능하다면 다시 던지지 마십시오. 오류가 눈에 띄지 않게 전달되지 않도록하십시오.

예:

void Main()
{
  try {
    DoStuff();
  }
  catch(Exception ex) {
    LogStuff(ex.ToString());
  }

void DoStuff() {
... Stuff ...
}

DoStuff가 잘못되면 어쨌든 보석금을 원할 것입니다. 예외는 main에 던져지고 ex의 스택 추적에서 일련의 이벤트를 볼 수 있습니다.


1

언제 예외를 다시 던져야합니까?

모든 곳에서, 그러나 최종 사용자 방법 ... 버튼 클릭 핸들러와 같은

어떤 종류의 중앙 오류 처리 메커니즘을 갖춰야합니까?

로그 파일을 작성합니다. WinForm 앱에서는 매우 쉽습니다.

throw 될 수있는 예외 처리는 디스크에 파일이 있는지 여부와 같은 선제 적 테스트에 비해 성능 저하가 있습니까?

나는 이것에 대해 확신하지 못하지만 예외를 처리하는 것이 좋은 습관이라고 생각합니다 ... 파일이 있는지 여부와 FileNotFoundException을 던지지 않는지 물어볼 수 있음을 의미합니다.

모든 실행 코드를 try-catch-finally 블록으로 묶어야합니까?

빈 catch 블록이 허용되는 경우가 있습니까?

예, 날짜를 표시하고 싶지만 그 날짜가 어떻게 저장 (dd / mm / yyyy, mm / dd / yyyy 등) 이었는지 알 수 없다고 가정 해 보겠습니다. tp 구문 분석을 시도하지만 실패하면 계속 진행합니다. . 당신과 관련이 없다면 ... 그렇다고 말할 것입니다.


1

나는 매우 빨리 배운 한 가지 둘러싸였다 절대적으로 모든 코드의 덩어리를 그와 상호 작용하는 것을 시도-catch 블록 내 프로그램 (예 : 파일 시스템, 데이터베이스 호출, 사용자 입력)의 흐름 외부. Try-catch는 성능 저하를 초래할 수 있지만 일반적으로 코드의 이러한 위치에서는 눈에 띄지 않으며 안전하게 비용을 지불합니다.

사용자가 실제로 "잘못된"작업을 수행 할 수있는 곳에서 빈 catch-block을 사용했지만 예외가 발생할 수 있습니다. 사용자가 DoubleCLicks 회색 자리 표시자를 선택하면 GridView에있는 예가 떠 오릅니다. 왼쪽 상단의 셀은 CellDoubleClick 이벤트를 발생 시키지만 셀은 행에 속하지 않습니다. 이 경우 실제로 메시지를 게시해야하지만 메시지를 잡지 않으면 사용자에게 처리되지 않은 예외 오류가 발생합니다.


1

예외를 다시 던질 때 키워드 자체가 던집니다. 이것은 잡힌 예외를 던지고 여전히 스택 추적을 사용하여 어디에서 왔는지 확인할 수 있습니다.

Try
{
int a = 10 / 0;
}
catch(exception e){
//error logging
throw;
}

이렇게하면 스택 추적이 catch 문에서 종료됩니다. (이것을 피하십시오)

catch(Exception e)
// logging
throw e;
}

.NET Framework 및 .NET Core의 최신 버전에도 계속 적용 되나요?
LuckyLikey

1

n 내 경험은 예외를 생성 할 것이라는 것을 알고있을 때 예외를 포착하는 데 적합하다고 생각했습니다. 웹 응용 프로그램에 있고 Response.Redirect를 수행하는 경우 System.ThreadAbortException이 발생한다는 것을 알고 있습니다. 의도적이기 때문에 특정 유형에 대한 캐치가 있고 그냥 삼켜 버립니다.

try
{
/*Doing stuff that may cause an exception*/
Response.Redirect("http:\\www.somewhereelse.com");
}
catch (ThreadAbortException tex){/*Ignore*/}
catch (Exception ex){/*HandleException*/}

1

나는 다음의 규칙에 깊이 동의합니다.

  • 오류가 눈에 띄지 않게 전달되지 않도록하십시오.

그 이유는 다음과 같습니다.

  • 코드를 처음 작성할 때 3 자 코드, .NET FCL 라이 러리 또는 동료의 최신 기여에 대한 완전한 지식이 없을 가능성이 큽니다. 실제로 모든 예외 가능성을 잘 알 때까지 코드 작성을 거부 할 수 없습니다. 그래서
  • 나는 알 수없는 것들로부터 자신을 보호하고 싶기 때문에 try / catch (Exception ex)를 사용하고 있음을 끊임없이 발견하고, 알다시피 OutOfMemoryException 등과 같이 더 구체적인 것이 아니라 예외를 포착합니다. 그리고 항상 예외를 만듭니다. ForceAssert.AlwaysAssert (false, ex.ToString ())에 의해 나 (또는 ​​QA)에게 팝업 됨);

ForceAssert.AlwaysAssert는 DEBUG / TRACE 매크로가 정의되었는지 여부에 관계없이 Trace.Assert의 개인적인 방법입니다.

개발주기는 다음과 같을 수 있습니다. 추악한 Assert 대화 상자를 발견했거나 다른 사람이 이에 대해 불평 한 다음 코드로 돌아와서 예외를 발생시키는 이유를 파악하고 처리 방법을 결정합니다.

이렇게하면 짧은 시간에 코드를 작성하고 알려지지 않은 도메인으로부터 나를 보호 할 수 있지만, 비정상적인 일이 발생하면 항상 알아 차리게되어 시스템이 더 안전하고 안전 해졌습니다.

개발자는 코드의 모든 세부 사항을 알아야하기 때문에 많은 분들이 저에게 동의하지 않으실 것임을 알고 있습니다. 솔직히 저는 또한 예전에는 순수 주의자였습니다. 하지만 요즘 나는 위의 정책이 더 실용적이라는 것을 배웠습니다.

WinForms 코드의 경우 항상 준수하는 황금률은 다음과 같습니다.

  • 항상 이벤트 핸들러 코드를 try / catch (Exception)

이것은 항상 사용 가능한 UI를 보호합니다.

성능 저하의 경우 성능 저하는 코드가 catch에 도달 할 때만 발생하며 실제 예외가 발생하지 않고 try 코드를 실행해도 큰 영향을 미치지 않습니다.

예외는 거의 발생하지 않아야합니다. 그렇지 않으면 예외가 아닙니다.


-1

사용자에 대해 생각해야합니다. 응용 프로그램 충돌은 마지막입니다사용자가 원하는 것. 따라서 실패 할 수있는 모든 작업에는 UI 수준에서 try catch 블록이 있어야합니다. 모든 메서드에서 try catch를 사용할 필요는 없지만 사용자가 작업을 수행 할 때마다 일반 예외를 처리 할 수 ​​있어야합니다. 그렇다고해서 첫 번째 경우에 예외를 방지하기 위해 모든 것을 확인하는 것이 결코 자유롭지는 않지만 버그가없는 복잡한 응용 프로그램은 없으며 OS가 예상치 못한 문제를 쉽게 추가 할 수 있으므로 예상치 못한 문제를 예상하고 사용자가 사용 하려는지 확인해야합니다. 작업은 앱이 충돌하기 때문에 데이터 손실이 없습니다. 앱이 중단되도록 할 필요가 없습니다. 예외를 포착하면 불확실한 상태가 아니며 사용자는 항상 충돌로 인해 불편을 겪습니다. 예외가 최상위 수준에 있더라도 충돌하지 않음은 사용자가 예외를 신속하게 재현하거나 최소한 오류 메시지를 기록 할 수 있으므로 문제를 해결하는 데 크게 도움이됩니다. 확실히 단순한 오류 메시지를받은 다음 Windows 오류 대화 상자 또는 이와 유사한 것을 보는 것보다 훨씬 더 많습니다.

그렇기 때문에 절대로 자만하고 앱에 버그가 없다고 생각해서는 안되며 보장되지 않습니다. 그리고 적절한 코드에 대한 try catch 블록을 래핑하고 오류 메시지를 표시하거나 오류를 기록 하는 것은 매우 작은 노력입니다.

사용자로서 나는 눈썹이나 사무실 앱 또는 어떤 것이 든 충돌 할 때마다 확실히 화가납니다. 예외가 너무 높아서 앱을 계속할 수없는 경우 단순히 충돌하는 것보다 해당 메시지를 표시하고 사용자에게 수행 할 작업 (다시 시작, 일부 OS 설정 수정, 버그보고 등)을 알리는 것이 좋습니다.


당신은 대답을 폭언처럼 덜 쓰고 대신 더 구체적이고 당신의 요점을 증명하려고 노력할 수 있습니까? 답변 방법도 살펴보십시오 .
LuckyLikey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.