프로그래밍/C#

[C#] try ~ finally

갓똥 2020. 4. 21. 18:28
728x90
반응형

1. 핵심 정리

using System;

class Program {
    static void Main() {
        try {
            throw new Exception();
        }
        catch(Exception e) {
            Console.WriteLine("catch");
        }
        finally {
            Console.WriteLine("finally");
        }
    }
}

 ① catch vs finally

실행 결과

catch
finally

 

using System;

class Program {
    static void Main() {
        try {
            // throw new Exception();
        }
        catch(Exception e) {
            Console.WriteLine("catch");
        }
        finally {
            Console.WriteLine("finally");
        }
    }
}
실행 결과

finally

 


2. 여러가지 테스트

using System;

class Program {
    static void Main() {
        try {
            throw new Exception();
        }
        /*
        catch(Exception e) {
            Console.WriteLine("catch");
        }
        */
        finally {
            Console.WriteLine("finally");
        }
    }
}
실행 결과

처리되지 않은 예외: System.Exception.....
위치: Program.Main() ....
finally

 ① catch 블록이 없을 경우

    => 예외를 보여준 후 finally 블록 실행

 

using System;

class Program {
    static void Main() {
        try {
            return;
            throw new Exception();
        }
        catch(Exception e) {
            Console.WriteLine("catch");
        }
        finally {
            Console.WriteLine("finally");
        }
    }
}
실행 결과

finally

 ② try 블록 내에서 return시 (예외 발생 전)

    => finally 블록 실행

 

using System;

class Program {
    static void Main() {
        return;
    
        try {
            throw new Exception();
        }
        catch(Exception e) {
            Console.WriteLine("catch");
        }
        finally {
            Console.WriteLine("finally");
        }
    }
}
실행 결과

 

 ③ try 블록 전에 return 시

    => try 블록 자체를 안탔으므로 finally도 제외

 


3. finally를 사용한 자원 관리 #1

using System;
using System.IO;

class Program {
    static void Main() {
        FileStream fs = null;
        
        fs = new FileStream("a.txt", FileMode.CreateNew);
        //...
        fs.Dispose();
    }
}

 ① C# 에서의 자원 관리

위는 파일을 관리하는 객체를 만들고 
9번 라인 //...에서 무언가 작업을 하고 자원을 해지하는 코드다.
그런데 무언가 작업을 하던 도중 예외가 발생해서 처리를 해줘야 하는 상황이 되었다.
try로 모든구문을 묶고 catch로 예외를 처리하려고 했는데 이렇게 되면
Dispose();전에 예외가 발생한 것이고 예외가 발생한 시점에 catch문으로 가므로
자원 해지를 못하게 된다.
이럴 경우 finally구문을 쓰면 해결할 수 있다.

 

using System;
using System.IO;

class Program {
    static void Main() {
        FileStream fs = null;
        
        try {
            fs = new FileStream("a.txt", FileMode.CreateNew);
            //...
            // fs.Dispose();
        }
        catch(Exception e) {
            // fs.Dispose();
        }
        finally {
            if(fs != null)
                fs.Dispose();
        }
    }
}

 


4. finally를 사용한 자원 관리 #2

using System;
using System.IO;

class Program {
    static void Main() {
        FileStream fs = new FileStream("a.txt", FileMode.CreateNew);
        
        try {
            //...
        }
        finally {
            fi(fs != null)
                fs.Dispose();
        }
    }
}

 

위의 코드는 자원을 관리하는 C#의 대표적인 코딩 기법이다.
정말 많이 사용하는 만큼 자동으로 위의 형태를 생성해주는 코드가 있다.

 

using System;
using System.IO;

class Program {
    static void Main() {
        // 1. using 사용
        using(FileStream fs = new FileStream("a.txt", FileMode.CreateNew)) {
            //...
        }
        
        // 2. 일반적인 자원 관리
        FileStream fs = new FileStream("a.txt", FileMode.CreateNew);
        
        try {
            //...
        }
        finally {
            fi(fs != null)
                fs.Dispose();
        }
    }
}

 

위의 코드에서 1번 방법과 2번 방법은 같은 코드로 볼 수 있다.
대신 2개의 코드 모두 자원 관리만 되어있고 예외에 대한 처리는 없으므로 그에 대한 처리를 해야한다.
try구문을 중첩해서 쓰는건 문제가 없으므로 using문 내에 사용하면 된다.

 

using System;
using System.IO;

class Program {
    static void Main() {
        using(FileStream fs = new FileStream("a.txt", FileMode.CreateNew)) {
            try {
                // 예외가 일어날 수 있는 작업
                //...
            }
            catch(Exception e) {
            }
        }
    }
}

 

위의 코드의 모양이 Dispose로 관리해야 하는 객체를 쓸 때
가장 많이 활용되는 코드의 모양이다.
728x90
반응형