programing

여러 캐치 블록을 사용한 VB.NET 캐치 시도

lovejava 2023. 6. 3. 07:52

여러 캐치 블록을 사용한 VB.NET 캐치 시도

이것은 정말 이상한 문제입니다.여러 개의 캐치 블록이 있는 트라이 캐치가 있습니다.첫 번째 캐치 블록에는 코드가 없고 주석만 있습니다.

Try
  'Some Code
Catch ex As ThreadAbortException
  'Do Nothing
Catch ex As Exception
  HandleException(ex)
End Try

ThreadAbortException 이외의 예외가 던져지면 예상대로 두 번째 Catch에 의해 잡힙니다.그러나 VS2010에서 코드를 실행할 때 ex 객체는 Nothing입니다.지금까지 이 문제를 "해결"할 수 있는 두 가지 방법을 찾았습니다.

수정 1: 첫 번째 예외 변수의 이름을 바꿉니다.

Try
  'Some Code
Catch tex As ThreadAbortException
  'Do Nothing
Catch ex As Exception
  HandleException(ex)
End Try

수정 2: 첫 번째 캐치 블록에 코드 줄을 추가합니다.

Try
  'Some Code
Catch ex As ThreadAbortException
  Dim i As Integer = 1
Catch ex As Exception
  HandleException(ex)
End Try

HandleException의 코드는 위의 경우에도 실행되면 제대로 작동하는 것 같습니다.Visual Studio 또는 디버거의 버그입니까?또는 위의 첫 번째 코드 블록이 올바르지 않은 경우가 있습니까?

이 모든 작업은 .NET 4.0에서 수행됩니다.

Teejay가 정답입니다.

하지만, 만약 당신이Catch블록이 비어 있으므로 이 예외를 처리하는 것이 전혀 의미가 없습니다.당신은 단지 마지막 블록이 그것을 잡지 못하게 하고 싶을 뿐입니다.방법을 사용할 수 있지만 비어 있는 것을 고려하십시오.Catch블록은 일반적으로 허용되지 않습니다. 예외는 포착되지 않거나 적절히 처리되어야 합니다. 예외를 소리 없이 삼키는 것은 버그로 간주되어야 합니다.귀하의 사례는 이 규칙의 예외이지만, 신중한 유지 관리자를 혼란스럽게 하기 때문에 코드로 문서화해야 합니다.

VB에는 정확히 이 상황에 대한 특별한 관용구가 있습니다.

Try
    ' …
Catch ex As Exception When Not TypeOf ex Is ThreadAbortException
    ' Only executed if `ex` isn’t a ThreadAbortException
End Try

이 코드가 인식되지 않습니다.ThreadAbortException만약 당신이 그것을 다루기를 원하지 않는다면, 그것이 옳은 일입니다.ThreadAbortException 삼킬 수 없기 때문에 당신이 그것을 잡았을 때에도, 그것은 마지막에 다시 던져질 입니다.Catch블록으로 막다

이는 기존의 시스템을 사용하는 시스템 드래곤의 답변과는 근본적으로 다릅니다.If여기 코드가 특별한 절을 사용하는 동안 진술.Catch문을 필터로 지정합니다.

VS의 디버거 버그인 것 같습니다.

증명

다음을 작성하는 경우:

Try
    Throw New InvalidOperationException("MESSAGE")
Catch ex As ArgumentException
    'Do Nothing
Catch ex As Exception
    Debug.WriteLine(ex)
End Try

그리고 당신은 보세요.ex로 평가됩니다.NothingQuickwatch 모드에서

그렇지만

콘솔에서 프로그램이 올바르게 인쇄합니다.System.InvalidOperationException: MESSAGE

좋아요, 자세히 설명해드리죠...

각 캐치마다 "결과"가 있어야 합니다.특정 캐치에 대해 아무 일도 일어나지 않으려면 해당 캐치를 포함하지 않거나 코드의 다른 위치로 이동시킵니다.

Try
   'Some Code
Catch ex As ThreadAbortException
   'Do something(ex: HandleExceptionSub())
Catch ex As Exception
   HandleException(ex)
End Try

만약 당신이 예외를 "잡는다면" 당신은 그것으로 무언가를 해야 합니다.

편집:

또한 트라이 캐치의 작동 방식에 대해 자세히 알려주는 데 도움이 되는 다음 정보를 찾았습니다.

다중 캐치 블록

시도 블록은 여러 개의 예외를 발생시킬 수 있으며, 이는 여러 개의 캐치 블록을 사용하여 처리할 수 있습니다.일반화된 캐치 블록보다 더 전문화된 캐치 블록이 먼저 와야 합니다.그렇지 않으면 컴파일러에 컴파일 오류가 표시됩니다.다중 캐치 블록

디버거의 "버그"가 아닙니다.디버거는 모든 예외를 찾고 처리하는 데 도움이 됩니다.

편집: 다른 게시물에서 읽은 내용에서 이 예외는 완전히 피할 수 있을 것 같습니다.그리고 그 예외를 다루지 않는 대신에 피하는 것이 좋을 것 같습니다.스레드 중단 예외 처리

편집: 시도 중인 여러 캐치 블록에 대한 자세한 정보를 방금 찾았습니다.이것은 MSDN에서 온 것이며 빈 캐치 블록 이후의 캐치 블록에는 절대 도달하지 않을 것이라고 말합니다.Catch Finally Statement 이것이 버그가 아니라 코드의 모든 예외를 처리하기 위한 예상 기능임을 추가로 증명합니다.

편집: 댓글에 있는 일부 사람들을 바로 잡기 위해 저는 이것이 정말 버그인지 확인하기 위해 매우 간단한 테스트 프로그램을 만들었습니다.제 연구 결과는 캐치 블록이 완벽하게 작동한다는 것입니다.MSDN 문서화된 여러 캐치 블록을 사용하여 Try Catch를 만드는 방법을 따르는 것은 그들이 말하는 대로 작동하는 것 같습니다.

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            if (textBox1.Text == "")
            {
                throw new ArgumentNullException("textBox1", "TextBox can not be empty");
            }
            else
            {
                MyString(textBox1.Text);
            }
        }
        catch (ArgumentNullException ex)
        {
            //nothing
        }
        catch (Exception ex)
        {
            MessageBox.Show("Test: " + ex.Message);
        }
    }

    private int MyString(string text)
    {
        return int.Parse(text);
    }

저는 버튼과 텍스트 상자로 간단한 양식을 만들었습니다.텍스트 상자가 비어 있으면 ArgumentNullException을 던지고 "MyString"에서 문자열을 "FormatException"을 던지는 정수로 구문 분석합니다."걸린" 예외를 처리하는 올바른 방법이 아닌 빈 캐치 블록을 갖는 것은 실제로 효과가 있습니다.그래서 제가 보기에는 이것은 벌레가 아닙니다.분명히 내가 Teejay와 Konrad에게 동의할 수 있는 유일한 것은 당신이 Trycatch 방법을 사용하여 ThreadAbortException을 잡고 처리할 수 없다는 것입니다.콘라드의 솔루션은 당신의 시도 캐치를 코딩하는 가장 좋은 방법입니다.

언급URL : https://stackoverflow.com/questions/14381963/vb-net-try-catch-with-multiple-catch-blocks