다음 코드 예제에서는 발생 가능한 FileNotFoundException을 try/catch 블록을 사용하여 catch합니다. try 블록의 뒤에는 데이터 파일을 찾지 못할 경우 FileNotFoundException을 catch하고 콘솔에 메시지를 표시하는 catch 블록이 있습니다. 그 다음 throw 문은 새 FileNotFoundException을 throw하고 텍스트 정보를 예외에 추가합니다.

using System;
using System.IO;

public class ProcessFile
{
   public static void Main()
      {
      FileStream fs = null;
      try   
      {
         //Opens a text tile.
         fs = new FileStream(@"C:\temp\data.txt", FileMode.Open);
         StreamReader sr = new StreamReader(fs);
         string line;

         //A value is read from the file and output to the console.
         line = sr.ReadLine();
         Console.WriteLine(line);
      }
      catch(FileNotFoundException e)
      {
         Console.WriteLine("[Data File Missing] {0}", e);
         throw new FileNotFoundException(@"data.txt not in c:\temp directory]",e);
      }
      finally
      {
         if (fs != null) 
            fs.Close();
      }
   }
}

Finally 블록 사용

예외가 발생하면 실행이 중단되며 가장 가까운 예외 처리기로 제어가 넘어갑니다. 이것은 항상 호출될 것으로 예상되는 일련의 코드가 실행되지 않음을 의미합니다. 파일 닫기와 같은 일부 리소스의 정리는 예외가 throw되어도 항상 실행되어야 합니다. 이렇게 하기 위해 finally 블록을 사용할 수 있습니다. finally 블록은 예외의 throw 여부에 관계없이 항상 실행됩니다.

using System;
class ArgumentOutOfRangeExample
   {
   static public void Main()
      {
      int[] array1={0,0};
      int[] array2={0,0};
         try
         {
         Array.Copy(array1,array2,-1);
         }
         catch (ArgumentOutOfRangeException e)
         {
         Console.WriteLine("Error: {0}",e);
         }
         finally
         {
         Console.WriteLine("This statement is always executed.");
         }
      }
   }

 

 

사용자 정의 예외 만들기

using System;
public class EmployeeListNotFoundException: Exception
{
   public EmployeeListNotFoundException()
      {
      }
   public EmployeeListNotFoundException(string message)
      : base(message)
      {
      }
   public EmployeeListNotFoundException(string message, Exception inner)
      : base(message, inner)
      {
      }
}

 

명시적으로 예외 Throw

throw 문을 사용하면 예외를 명시적으로 throw할 수 있으며 catch된 예외를 throw 문을 사용하여 다시 throw할 수도 있습니다. 디버깅할 때 더 많은 정보를 제공할 수 있도록 다시 throw한 예외에는 정보를 추가하는 것이 좋은 코드 작성 방법입니다.

다음 코드 예제에서는 발생 가능한 FileNotFoundException을 try/catch 블록을 사용하여 catch합니다. try 블록의 뒤에는 데이터 파일을 찾지 못할 경우 FileNotFoundException을 catch하고 콘솔에 메시지를 표시하는 catch 블록이 있습니다. 그 다음 throw 문은 새 FileNotFoundException을 throw하고 텍스트 정보를 예외에 추가합니다.

using System;
using System.IO;

public class ProcessFile
{
   public static void Main()
      {
      FileStream fs = null;
      try   
      {
         //Opens a text tile.
         fs = new FileStream(@"C:\temp\data.txt", FileMode.Open);
         StreamReader sr = new StreamReader(fs);
         string line;

         //A value is read from the file and output to the console.
         line = sr.ReadLine();
         Console.WriteLine(line);
      }
      catch(FileNotFoundException e)
      {
         Console.WriteLine("[Data File Missing] {0}", e);
         throw new FileNotFoundException(@"data.txt not in c:\temp directory]",e);
      }
      finally
      {
         if (fs != null) 
            fs.Close();
      }
   }
}

 

런타임 예외계층

Exception

Object 모든 예외의 기본 클래스입니다.

없음(이 예외의 파생 클래스를 사용함)

SystemException

Exception 

모든 런타임 생성 오류의 기본 클래스입니다.

없음(이 예외의 파생 클래스를 사용함)

IndexOutOfRangeException

SystemException 배열이 올바르지 않게 인덱싱되는 경우에만 런타임에 의해 throw됩니다.

배열의 인덱스가 유효한 범위를 벗어남

arr[arr.Length+1]

NullReferenceException

SystemException null 개체가 참조되는 경우에만 런타임에 의해 throw됩니다.

object o = null;

o.ToString();

AccessViolationException

SystemException

잘못된 메모리가 액세스되는 경우에만 런타임에 의해 throw됩니다.

비관리 코드 또는 안전하지 않은 관리 코드와 상호 운용하면서 잘못된 포인터가 사용될 때 발생합니다.

InvalidOperationException

SystemException

유효하지 않은 상태에 있을 때 메서드에 의해 throw됩니다.

내부 컬렉션에서 Item을 제거한 후 Enumerator.GetNext() 호출

ArgumentException

SystemException 모든 인수 예외의 기본 클래스입니다.

없음(이 예외의 파생 클래스를 사용함)

ArgumentNullException

ArgumentException

인수에 null을 허용하지 않는 메서드에 의해 throw됩니다.

String s = null;

"Calculate".IndexOf (s);

ArgumentOutOfRangeException

ArgumentException

인수가 지정된 범위에 있는지 검사하는 메서드에 의해 throw됩니다.

String s = "string";

s.Chars[9];

ExternalException

SystemException

런타임 외부에서 발생하거나 런타임 외부의 환경을 대상으로 하는 예외의 기본 클래스입니다.

없음(이 예외의 파생 클래스를 사용함)

ComException

ExternalException

COM HRESULT 정보를 캡슐화하는 예외입니다.

COM interop에 사용

SEHException

ExternalException

Win32 구조의 예외 처리 정보를 캡슐화하는 예외입니다.

비관리 코드 interop에 사용

 

 

최선의 예외 처리 구현 방법

try/catch 블록을 설정할 시점을 알아야 합니다. 예를 들면,발생 가능성이 있는 조건을 예외 처리를 사용하지 않고 프로그래밍 방식으로 검사할 수 있습니다. 그 외의 상황에서는 예외 처리를 사용하여 오류 조건을 catch하는 것이 좋습니다.

   if(conn.State != ConnectionState.Closed)
      conn.Close();

프로그래밍적으로 처리해주고 예외처리를 하는게 좋다

   try {
     conn.Close();
   }
   catch(InvalidOperationException ex) {
     //Do something with the error or ignore it.
   }

+ Recent posts