C #에서 마지막으로 사용하는 이유는 무엇입니까?


189

finally 블록 안에 무엇이 있든 항상 (거의) 실행되므로 코드를 묶거나 닫지 않는 것의 차이점은 무엇입니까?


3
닫히지 않고 무엇을 의미합니까?
Ramesh 2012

5
그리고 "(거의)"는 무엇을 의미합니까?
Beska

49
컴퓨터가 try 절을 실행하는 동안 전원 코드를 뽑으면 finally 절이 호출되지 않습니다.
Dour High Arch

5
lol, 그렇습니다, 맞습니다, 그러나 당신은 그것을 정말로 코딩 할 수 없습니다?
Ed S.

2
@Ed : 거래를 사용하십시오. try 절은 finally 절의 단일 원자 변경으로 유지 될 수있는 일종의 임시 또는 메모리 내 변경을 수행해야합니다. 이것은 쉬운 일이 아니며 특별한 하드웨어가 필요할 수 있습니다.
Dour High Arch

답변:


405

finally 블록 내부의 코드는 예외가 있는지 여부에 관계없이 실행됩니다. 이것은 항상 연결을 닫는 것처럼 실행해야하는 특정 하우스 키핑 기능에 매우 유용합니다.

자, 당신의 질문이 당신이 이것을 해야하는 이유 라고 생각 합니다.

try
{
    doSomething();
}
catch
{
    catchSomething();
}
finally
{
    alwaysDoThis();
}

당신이 할 수있을 때 :

try
{
    doSomething();
}
catch
{
    catchSomething();
}

alwaysDoThis();

대답은 catch 문 내부의 코드가 많은 경우 예외를 다시 발생 시키거나 현재 함수에서 벗어날 것입니다. 후자의 코드에서 "alwaysDoThis ();" catch 문 내의 코드가 반환을 발생 시키거나 새 예외를 throw하면 호출이 실행되지 않습니다.


3
흠. 내가 말한 것과 매우 유사하지만 더 명확하고 정확합니다. 확실한 +1.
Beska

46
이것은 try {} 블록 내부의 "return"에도 적용됩니다.
Lucas

4
실제로 catch {} 블록 없이도 적용됩니다 (시도 / 마지막으로 예외가 발생하도록 함)
Lucas

더 나은 내 광산, 직장에 있었고 그것을 자세히 답변 10 분을 보내고 싶지 않았다. +1
Matt Briggs

2
그렇습니다, 이것은 내가 생각했던 것과 정확히 같습니다 : D 이제 이해합니다.
Rodrigo

62

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).
}

이 동작은 특히 블록을 사용 하는 것이 더 좋지만 특히 정리 (자원 처리)를 수행해야 할 때 다양한 상황에서 매우 유용합니다 .


2
이것은 말 그대로 내가 마지막으로 사용하는 유일한 이유이다
크리스토퍼 타운센드

12

스트림 리더, 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();
        }

오류가있는 경우 연결 개체가 자동으로 삭제되지만 오류를 캡처하지는 않습니다.


2
Dispose ()는 연결을 닫을 수도 있으므로 둘 다 호출 할 필요는 없습니다. Close ()는 Dipose ()하지 않으며 연결을 다시 열 수 있습니다.
Lucas

사용에 대해 언급 해 주셔서 감사합니다. 그렇지 않으면 대답해야합니다.
Dan Rosenstark 09 년

11

catch 블록에서 예외를 처리하지 않더라도 마지막으로 실행되기 때문입니다.


7

마지막으로 명령문은 리턴 후에도 실행될 수 있습니다.

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
}

7

finally다음과 같이

try {
  // do something risky
} catch (Exception ex) {
  // handle an exception
} finally {
  // do any required cleanup
}

try..catchtry 블록에서 예외가 발생했는지 여부에 관계없이 블록 뒤에 코드를 실행할 수있는 보장 된 기회 입니다.

따라서 리소스 해제, DB 연결, 파일 핸들 등과 같은 작업에 적합합니다.


3
이러한 모든 예는 일반적으로 using 블록을 사용하는 것이 더 좋지만 실제로 대답을 방해하지는 않습니다.
Joel Coehoorn

4

나는와 마지막의 사용을 설명합니다 파일 리더 예외

  • 마지막으로 사용하지 않고
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();
    }
}

행복한 코딩 :)

참고 : "@"은 "인식 할 수없는 이스케이프 시퀀스"오류를 피하기 위해 완전 문자열 을 작성하는 데 사용됩니다 . @ 기호는 해당 문자열을 그대로 읽고 제어 문자를 해석하지 않는다는 의미입니다.


2

대기 (모래 시계) 커서 대신 기본 포인터로 커서를 다시 설정해야한다고 가정합니다. 커서를 설정하기 전에 예외가 발생하고 앱이 완전히 중단되지 않으면 혼란스러운 커서가 남을 수 있습니다.


2

때로는 예외를 처리하고 싶지 않지만 (캐치 블록 없음) 정리 코드를 실행하려고 할 때가 있습니다.

예를 들면 다음과 같습니다.

try
{
    // exception (or not)
}
finally
{
    // clean up always
}

예외가 발견되지 않으면 finally 블록의 실행은 운영 체제가 예외 해제 작업을 트리거하도록 선택하는지 여부에 따라 다릅니다.
Vikas Verma

2

finally 블록 은 try 블록에 할당 된 모든 리소스를 정리하고 예외가 있어도 실행해야하는 코드를 실행하는 데 유용합니다. try 블록이 어떻게 종료되는지에 관계없이 제어는 항상 finally 블록으로 전달됩니다.


1

아 .. 네가 무슨 말을하는지 알 것 같아! 잠깐만 .. "최종 블록 이후에 그리고 마지막으로 try-catch-finally 외부에서 finally 블록에 배치하는 이유"가 궁금합니다.

예를 들어, 오류가 발생하면 실행이 중지되었지만 열린 파일, 데이터베이스 연결 등과 같은 리소스를 정리하려고하기 때문일 수 있습니다.


1

최종 블록의 제어 흐름은 Try 또는 Catch 블록 뒤에 있습니다.

[1. First Code]
[2. Try]
[3. Catch]
[4. Finally]
[5. After Code]

3에 Return 문이 1> 2> 3> 4 인 경우 예외 1> 2> 3> 4> 5

2에 리턴 문이있는 경우 예외> 1> 2> 4> 5없이 1> 2> 4


0

설명서 에서 언급했듯이 :

catch와 마지막으로 함께 사용하는 일반적인 용도는 try 블록에서 리소스를 가져 와서 사용하고 catch 블록에서 예외적 인 상황을 처리하고 finally 블록에서 리소스를 해제하는 것입니다.

이것을 읽는 것도 가치가 있습니다 .

일치하는 catch 절이 발견되면 시스템은 catch 절의 첫 번째 명령문으로 제어를 전송하도록 준비합니다. catch 절의 실행이 시작되기 전에 시스템은 먼저 try 문과 관련된 finally 절을 예외를 잡은 것보다 중첩 된 순서로 실행합니다.

따라서 finally절에 상주하는 코드 는 이전 catch절에 return문 이 있어도 실행됩니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.