728x90
반응형
1. 핵심 정리
using System;
using System.Net;
class Program {
static void Main() {
WebClient wc = new WebClient();
try {
stirng s = wc.DownloadString("http://wwww.nnaver.ccom");
}
catch(WebException e) {
if(e.Status == WebExceptionStatus.NameResolutionFailure)
Console.WriteLine("URL 입력 에러");
else if(e.Status == WebExceptionStatus.Timeout)
Console.WriteLine("시간 초과");
else
Console.WriteLine("다른 문제");
}
catch(Exception e) {
}
wc.Dispose();
}
}
웹 클라이언트 객체를 만들어 특정 웹사이트의 문자를 꺼내오려했는데
오타가 나서 예외가 발생하는 상황이다.
앞서 보았던것은 입력값 오류, null, 스레드간 동시 호출의 예외가 있었는데
각 항목별로 조금 더 자세하게 받아올 수 있다.
Exception 클래스의 멤버로 Status가 있는데 이를 이용한 방법이다.
각 예외에 대한 Status도 존재한다.
정의로 이동해보면 enum타입으로 있다.
각 예외에 대해 다르게 작성할 수 있어서 위와 같이 URL오류, 시간 초과의 문제로 나누었다.
하지만 접속 실패, 기타 필요한 예외 처리를 하면 할수록 코드가 길어질텐데
이럴 때 예외 필터란 것을 쓸 수 있다.
using System;
using System.Net;
class Program {
static void Main() {
WebClient wc = new WebClient();
try {
stirng s = wc.DownloadString("http://wwww.nnaver.ccom");
}
catch(WebException e) when(e.Status == WebExceptionStatus.NameResolutionFailuer) {
Console.WriteLine("URL 입력 에러");
}
catch(WebException e) when(e.Status == WebExceptionStatus.Timeout) {
Console.WriteLine("시간 초과");
}
catch(Exception e) {
}
wc.Dispose();
}
}
필요한 예외를 골라 참일 경우 해당 catch문을 실행한다.
C# 6.0부터 지원하는 문법이다.
2. 활용
using System;
class Server {
public void Connect() {
throw new TimeoutException();
}
}
class Program {
static void Foo() {
Server wc = new Server();
try {
wc.Connect();
}
catch(Exception e) when(Logging(e)) {
Console.WriteLine("Foo catch");
}
}
static bool Logging(Exception e) {
Console.WriteLine($"LOG : {e.Message}");
return false;
}
static void Main() {
try {
Foo();
}
catch (Exception e) {
Console.WriteLine("처리");
}
}
}
위 코드에서 예외 필터의 활용 사례를 볼 수 있다.
상황 자체는 서버에 접속하려 하지만 무조건 예외를 뱉게 되어있다.
예외에 대한 처리가 Foo함수와 Main함수에 있는데
Foo에서 먼저 처리를 하고 Main에서 처리를 할 것이다.
근데 자세히 보면 Foo에서는 예외가 발생해도 catch문을 실행하지 않는다.
왜냐하면 예외 필터는 해당 예외가 참일 때 실행되는데 Logging함수는 항상 false를 뱉는다.
따라서 catch문을 실행하지 않는다.
그럼 왜 이렇게 썼을까?
답은 함수이름과 같이 로깅을 위해 쓴 것이다.
catch문을 실행하게 되면 약간의 성능저하가 발생되는데 로그만 찍어주고 catch문에 들어가지 않으므로
성능저하를 줄일 수 있다.
① 성능 저하를 줄이기 위해
using System;
class Server {
public void Connect() {
throw new TimeoutException();
}
}
class Program {
static void Foo() {
int retryCount = 0;
bool bSuccess = false;
Server wc = new Server();
while(bSuccess == false) {
try {
wc.Connect();
bSuccess = true;
}
catch(TimeoutException e) {
if(++retryCount < 4)
Console.WriteLine("다시 시도");
else
throw;
}
}
}
static void Main() {
try {
Foo();
}
catch (Exception e) {
Console.WriteLine("예외 처리");
}
}
}
다시 이전 코드와 비슷하지만 조금 다른 코드이다.
bSuccess로 접속 여부를 판단하여 접속이 안된다면 로그를 찍고 다시 접속을 시도한다.
3번의 실패가 일어나게되면 Main으로 예외를 던져 처리하게 되는 코드이다.
충분히 있을 수 있는 코드인데 이 코드도 문제는 catch를 총 4번 처리한다는 것이다.
앞서 말했듯이 catch는 약간의 성능 저하가 생기므로 되도록 횟수를 줄이는 것이 좋다.
이것도 예외 필터를 사용해 해결 가능하다.
using System;
class Server {
public void Connect() {
throw new TimeoutException();
}
}
class Program {
static void Foo() {
int retryCount = 0;
bool bSuccess = false;
Server wc = new Server();
while(bSuccess == false) {
try {
wc.Connect();
bSuccess = true;
}
catch(TimeoutException e) when(++retryCount < 4) {
Console.WriteLine("다시 시도");
}
}
}
static void Main() {
try {
Foo();
}
catch (Exception e) {
Console.WriteLine("예외 처리");
}
}
}
예외 필터가 참일 경우만 실행되는 것을 이용하여 위와 같이 할 수 있다.
728x90
반응형
'프로그래밍 > C#' 카테고리의 다른 글
[C#] 컬렉션 (Collection) (0) | 2020.04.23 |
---|---|
[C#] try ~ finally (0) | 2020.04.21 |
[C#] 예외를 처리하는 방법 (catch, Exception, rethrow) (0) | 2020.04.20 |
[C#] 예외 처리 (0) | 2020.04.17 |
[C#] 람다 표현식 (Lambda Expression) (0) | 2020.04.16 |