Programing/dotnet core

dotnetcore : try catch finally vs using

Ezzi 2020. 2. 19. 13:21
반응형

Finally

 

보통 예외 발생 여부의 체크를 위해서 보통 try ~ catch 문을 다음과 같은 형태로 많이 사용합니다. 

try
{
	somthing your code
}
catch (Exception e)
{
	Console.WriteLine(e.Message);
}    

여기서 finally를 추가 적으로 작성해주면 예외 발생 여부에 상관없이 무조건 호출 되게 됩니다.

 

그래서 파일이나/데이타베이스 같은 unmanaged resource를 사용할 때 finally를 사용하게 되면

 

예외 발생 여부와 상관없이 리소스 해제를 보장할 수 있습니다. 

 

코드를 보겠습니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.IO;
 
namespace trycatchfinally
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = "test.txt";
            StreamWriter sw = null;
            try
            {                
                // streamwriter를 사용하고 아직 해제 하지 않은 상태
                sw = new StreamWriter(filePath);
                sw.WriteLine("Hello World");
 
                // 예외상황을 강제로 발생 시켜줌
                object obj = null;
                int temp = (int)obj;
            }   
            catch (Exception e)                      
            {
                // 예외 상황에 대해서 출력
                Console.WriteLine(e.Message);
            }
            finally
            {
                // 예외가 발생하더라도 리소스 해제를 보장 함
                sw.Dispose();
                Console.WriteLine("finally");
            }
        }
    }
}
 
cs

 

코드를 실행해 보면 결과는 다음과 같이 나오게 됩니다. 

예외가 발생하여 catch에서 message를 출력은 했지만 finally를 통과 하면서 리소스를 해제 하였습니다.

 

 

Using

 

위와 같은 상황을 using을 통해서 쓰게 되면 dipose를 해줄 필요가 없습니다.

 

실험을 해보기 위해서 위의 코드를 약간 수정해서 2가지 케이스로 살펴 보겠습니다.

 

1. 먼저 using을 사용하지 않았을 경우 입니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
static void Main(string[] args)
{
    string filePath = "test.txt";
 
    // case 1            
    StreamWriter sw1 = new StreamWriter(filePath);
    sw1.WriteLine("miss dispose");
    
    StreamWriter sw = null;
    try
    {                
        // 파일스트림을 사용하고 아직 해제 하지 않은 상태
        sw = new StreamWriter(filePath);
        sw.WriteLine("Hello World");
 
        // 예외상황을 강제로 발생 시켜줌
        object obj = null;
        int temp = (int)obj;
    }   
    catch (Exception e)                      
    {
        // 예외 상황에 대해서 출력
        Console.WriteLine(e.Message);
    }
    finally
    {
        // 예외가 발생하더라도 리소스 해제를 보장 함
        sw.Dispose();
        Console.WriteLine("finally");
    }
}
cs

당연히 위에서 동일한 파일에 접근하면서 리소스 해제를 안해줬기 때문에 에러가 나게 됩니다. 

 

 

2. 동일한 코드를 using으로 묶어 보겠습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
static void Main(string[] args)
{
    string filePath = "test.txt";
    
    // case 1            
    //StreamWriter sw1 = new StreamWriter(filePath);
    //sw1.WriteLine("miss dispose");
 
    // case 2
    using (StreamWriter sw1 = new StreamWriter(filePath))
    {
        sw1.WriteLine("use using");
        Console.WriteLine("this is Using");
    }
    
    StreamWriter sw = null;
    try
    {                
        // 파일스트림을 사용하고 아직 해제 하지 않은 상태
        sw = new StreamWriter(filePath);
        sw.WriteLine("Hello World");
 
        // 예외상황을 강제로 발생 시켜줌
        object obj = null;
        int temp = (int)obj;
    }   
    catch (Exception e)                      
    {
        // 예외 상황에 대해서 출력
        Console.WriteLine(e.Message);
    }
    finally
    {
        // 예외가 발생하더라도 리소스 해제를 보장 함
        sw.Dispose();
        Console.WriteLine("finally");
    }
}
cs

 

 

그리고 실행 결과를 보면

 

 

using 문을 통과 하고 따로 dispose를 안해줘도 리소스 해제가 되었고 

두번째 try ~~ 코드도 제대로 수행 된 것을 확인할 수 있습니다.

 

결론은 using을 쓰게 되면 코드가 간결해 진다는 것입니다. 

 

 

github 링크

 

https://github.com/Helloezzi/trycatchfinally_vs_using

 

Helloezzi/trycatchfinally_vs_using

Contribute to Helloezzi/trycatchfinally_vs_using development by creating an account on GitHub.

github.com

 

반응형