본문 바로가기
C# 기술

C# try catch finally 제대로 쓰기

by bryan.oh 2019. 1. 20.
반응형

try catch finally

C#

 

try 문 실행 순서 예제

 

정상적인 종료 (Exception 발생 안할 때)

private string tryTest()
{
    try
    {
        Console.WriteLine("#try");
        return "return in Try";
    }
    catch(Exception ex)
    {
        Console.WriteLine("#catch");
        return ex.Message;
    }
    finally
    {
        Console.WriteLine("#finally");
    }
}
 

이 소스의 실행 순서는

1
2
3
#try
#finally
 
cs

입니다. 

return 하기 전에 finally 문이 실행됩니다.

 

 

만약 Exception 이 발생하면 어떻게 될까요?

private string exceptionTest()
{
    try
    {
        Console.WriteLine("try #1");
        Dictionary<string, string> dic = new Dictionary<string, string>();
        Console.WriteLine("exception 발생 : " + dic["hey"]);
        Console.WriteLine("try #2");
        return "정상종료";
    }
    catch (Exception ex)
    {
        Console.WriteLine("catch #1 " + ex.Message);
        return "catch 에서 종료";
    }
    finally
    {
        Console.WriteLine("finally #1");
    }
}
 

 

실행 순서는 어떻게 될까요?

string result = exceptionTest();
Console.WriteLine("result = " + result);
 

실행 후 출력창을 확인해보겠습니다.

try #1
'HelloWorldTest.exe'(CLR v4.0.30319: HelloWorldTest.exe): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_ko_b77a5c561934e089\mscorlib.resources.dll'을(를) 로드했습니다. 모듈이 기호 없이 빌드되었습니다.
예외 발생: 'System.Collections.Generic.KeyNotFoundException'(mscorlib.dll)
catch #1 지정한 키가 사전에 없습니다.
finally #1
result = catch 에서 종료

 

Exception 이 발생하고 catch 문의 끝에 return 이 있는데도 finally 가 실행되네요.

 

 

아래는 실행된 순서를 표시해둔겁니다.

 
private string exceptionTest()
{
    try
    {
        Console.WriteLine("try #1"); (1)
        Dictionary<string, string> dic = new Dictionary<string, string>();
        Console.WriteLine("exception 발생 : " + dic["hey"]); // 여기부터 실행 안됨
        Console.WriteLine("try #2");
        return "정상종료";
    }
    catch (Exception ex)
    {
        Console.WriteLine("catch #1 " + ex.Message); (2)
        return "catch 에서 종료"; (4)
    }
    finally
    {
        Console.WriteLine("finally #1"); (3)
    }
}

 

 

finally 문 안에서 Exception 이 발생하면 ?

private string finallyExceptionTest()
{
    try
    {
        Console.WriteLine("# try 1");
        String aaa = null;
        aaa.Substring(0, 1);    // exception 발생
        Console.WriteLine("# try 2");
    }
    catch(Exception ex)
    {
        Console.WriteLine("# catch");
    }
    finally
    {
        Console.WriteLine("# finally 1");
        String aaa = null;
        aaa.Substring(0, 1);    // exception 발생
        Console.WriteLine("# finally 2");
    }
    return "";
}

이 소스는 어떤 순서로 실행될까요?

 

결과는,

이렇게 나옵니다.

Debug 에서는 프로그램이 종료되고 위와같이 나오죠.

Release 후에 사용자가 프로그램을 사용할땐 Windows 경고창이 뜨면서 프로그램이 강제 종료됩니다.

한창 작업중이었다면 작업중이던 데이터가 모두 날라가 사용자가 분노하겠죠?

 

그래서 

fianlly 문 안에서 또 다른 작업을 하기 위해서는, 예외처리를 꼭 해야합니다.  finally 안에서 또 try문을 써야합니다.

 

 

 

 

catch 문 상황별로 쓰기

try
{
    Console.WriteLine("#try");
    return "return in Try";
}
catch(FileNotFoundException ex)
{
    MessageBox.Show("파일을 찾을 수 없습니다");
    return ex.Message;
}catch(SqlException se)
{
    MessageBox.Show("SQL 문 오류가 발생했습니다");
    return se.ToString();
}
finally
{
    Console.WriteLine("#finally");
}

위와 같이 try 문 안에서 어떤 상황에 따라 Exception 이 발생했는지, catch 할 수 있습니다. 그래서 catch 문인가 봅니다.(제 생각에;;)

파일이 없을 때 메시지 또는 어떤 처리를 해야한다면 파일이 없을 때 발생하는 FileNotFoundException 을 catch 문에 추가합니다.

그 밖에 SqlException, InvalidCastException, IndexOutOfRangeException 등등 아주 많은 Exception 이 있는데, 

상황에 따라 써주시면 됩니다.

 

위의 소스에서 IndexOutOfRangeException 이 발생하면 어떻게 될까요?

프로그램이 죽습니다. 예외 처리 되지 않아서죠.

가장 안전한 방법은, 마지막 catch 문을 추가하고 Exception 으로 잡아주면 됩니다.

try
{
    Console.WriteLine("#try");
    return "return in Try";
}
catch(FileNotFoundException ex)
{
    MessageBox.Show("파일을 찾을 수 없습니다");
    return ex.Message;
}catch(SqlException se)
{
    MessageBox.Show("SQL 문 오류가 발생했습니다");
    return se.ToString();
}catch(Exception ex)
{
    MessageBox.Show(ex.ToString());
    return "위에 정의되지 않은 Exception은 여기로";
}
finally
{
    Console.WriteLine("#finally");
}
 

 

 

2019/01/19 - [C# Windows Form 개발 따라하기] - [006] Dictionary 사용법. 기본,응용

2019/01/19 - [C# 기술] - TextBox 숫자만 입력 ( Windows Form C# )

728x90
반응형

댓글