finally 블록 안에 무엇이 있든 항상 (거의) 실행되므로 코드를 묶거나 닫지 않는 것의 차이점은 무엇입니까?
finally 블록 안에 무엇이 있든 항상 (거의) 실행되므로 코드를 묶거나 닫지 않는 것의 차이점은 무엇입니까?
답변:
finally 블록 내부의 코드는 예외가 있는지 여부에 관계없이 실행됩니다. 이것은 항상 연결을 닫는 것처럼 실행해야하는 특정 하우스 키핑 기능에 매우 유용합니다.
자, 당신의 질문이 당신이 이것을 해야하는 이유 라고 생각 합니다.
try
{
doSomething();
}
catch
{
catchSomething();
}
finally
{
alwaysDoThis();
}
당신이 할 수있을 때 :
try
{
doSomething();
}
catch
{
catchSomething();
}
alwaysDoThis();
대답은 catch 문 내부의 코드가 많은 경우 예외를 다시 발생 시키거나 현재 함수에서 벗어날 것입니다. 후자의 코드에서 "alwaysDoThis ();" catch 문 내의 코드가 반환을 발생 시키거나 새 예외를 throw하면 호출이 실행되지 않습니다.
try-finally를 사용하면 얻을 수있는 대부분의 이점이 이미 지적되었지만 다음 중 하나를 추가 할 것이라고 생각했습니다.
try
{
// Code here that might throw an exception...
if (arbitraryCondition)
{
return true;
}
// Code here that might throw an exception...
}
finally
{
// Code here gets executed regardless of whether "return true;" was called within the try block (i.e. regardless of the value of arbitraryCondition).
}
이 동작은 특히 블록을 사용 하는 것이 더 좋지만 특히 정리 (자원 처리)를 수행해야 할 때 다양한 상황에서 매우 유용합니다 .
스트림 리더, db 요청 등과 같은 관리되지 않는 코드 요청을 사용할 때마다; 예외를 잡으려면 try catch finally를 사용하고 마지막으로 스트림, 데이터 리더 등을 닫으십시오. 오류가 발생하지 않을 때 연결이 닫히지 않으면 DB 요청으로 실제로 나쁜 것입니다.
SqlConnection myConn = new SqlConnection("Connectionstring");
try
{
myConn.Open();
//make na DB Request
}
catch (Exception DBException)
{
//do somehting with exception
}
finally
{
myConn.Close();
myConn.Dispose();
}
오류를 잡고 싶지 않다면
using (SqlConnection myConn = new SqlConnection("Connectionstring"))
{
myConn.Open();
//make na DB Request
myConn.Close();
}
오류가있는 경우 연결 개체가 자동으로 삭제되지만 오류를 캡처하지는 않습니다.
마지막으로 명령문은 리턴 후에도 실행될 수 있습니다.
private int myfun()
{
int a = 100; //any number
int b = 0;
try
{
a = (5 / b);
return a;
}
catch (Exception ex)
{
Response.Write(ex.Message);
return a;
}
// Response.Write("Statement after return before finally"); -->this will give error "Syntax error, 'try' expected"
finally
{
Response.Write("Statement after return in finally"); // --> This will execute , even after having return code above
}
Response.Write("Statement after return after finally"); // -->Unreachable code
}
finally
다음과 같이
try {
// do something risky
} catch (Exception ex) {
// handle an exception
} finally {
// do any required cleanup
}
try..catch
try 블록에서 예외가 발생했는지 여부에 관계없이 블록 뒤에 코드를 실행할 수있는 보장 된 기회 입니다.
따라서 리소스 해제, DB 연결, 파일 핸들 등과 같은 작업에 적합합니다.
나는와 마지막의 사용을 설명합니다 파일 리더 예외 예
try{ StreamReader strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine(strReader.ReadeToEnd()); StreamReader.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); }
위의 예제에서 Data.txt 라는 파일 이 없으면 예외가 발생하고 처리되지만 호출 된 명령문 은 실행되지 않습니다. 이로 인해 리더와 관련된 리소스가 릴리스되지 않았습니다.StreamReader.Close();
StreamReader strReader = null; try{ strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine(strReader.ReadeToEnd()); } catch (Exception ex){ Console.WriteLine(ex.Message); } finally{ if (strReader != null){ StreamReader.Close(); } }
행복한 코딩 :)
참고 : "@"은 "인식 할 수없는 이스케이프 시퀀스"오류를 피하기 위해 완전 문자열 을 작성하는 데 사용됩니다 . @ 기호는 해당 문자열을 그대로 읽고 제어 문자를 해석하지 않는다는 의미입니다.
때로는 예외를 처리하고 싶지 않지만 (캐치 블록 없음) 정리 코드를 실행하려고 할 때가 있습니다.
예를 들면 다음과 같습니다.
try
{
// exception (or not)
}
finally
{
// clean up always
}
finally 블록 은 try 블록에 할당 된 모든 리소스를 정리하고 예외가 있어도 실행해야하는 코드를 실행하는 데 유용합니다. try 블록이 어떻게 종료되는지에 관계없이 제어는 항상 finally 블록으로 전달됩니다.
설명서 에서 언급했듯이 :
catch와 마지막으로 함께 사용하는 일반적인 용도는 try 블록에서 리소스를 가져 와서 사용하고 catch 블록에서 예외적 인 상황을 처리하고 finally 블록에서 리소스를 해제하는 것입니다.
이것을 읽는 것도 가치가 있습니다 .
일치하는 catch 절이 발견되면 시스템은 catch 절의 첫 번째 명령문으로 제어를 전송하도록 준비합니다. catch 절의 실행이 시작되기 전에 시스템은 먼저 try 문과 관련된 finally 절을 예외를 잡은 것보다 중첩 된 순서로 실행합니다.
따라서 finally
절에 상주하는 코드 는 이전 catch
절에 return
문 이 있어도 실행됩니다 .