55

사용하는 것이 적절한 상황이 있습니까?try-finally없는 블록catch블록?


11 답변


88

당신은 그것을 사용하여 어떤 행동이try콘텐츠 또는 예외 상황을 제외하고는 예외를 사용할 수 없습니다.

그냥 명확히하기 위해, 이것은 예외를 숨기지 않습니다. 그만큼finally예외가 호출 스택 위로 전파되기 전에 블록이 실행됩니다.

또한 실수로 사용하면using키워드로 컴파일됩니다.try-finally(정확한 변환은 아니지만 논쟁의 여지가 있으므로 충분히 가깝습니다).

try
{
    TrySomeCodeThatMightException();
}
finally
{
    CleanupEvenOnFailure();
}

코드 실행 중finally실행이 보장되지는 않지만 보장되지 않는 경우는 상당히 뚜렷합니다. 기억이 안납니다. 내가 기억하는 전부는, 만약 당신이 그런 경우에, 기회가 아주 좋은 것입니다.finally기본적으로 땀을 흘리지 않아도됩니다.

토비아스에서 업데이트 : finally프로세스가 종료되면 실행되지 않습니다.

Paddy에서 업데이트 : 마지막으로 .net try..finally 블록에서 실행되지 않는 조건

가장 보편적 인 예제는 코드가 실패하더라도 데이터베이스 연결이나 외부 리소스를 삭제하는 것입니다.

using (var conn = new SqlConnection("")) // Ignore the fact we likely use ORM ;-)
{
    // Do stuff.
}

~으로 컴파일어떤 것처럼:

SqlConnection conn;

try
{
    conn = new SqlConnection("");
    // Do stuff.
}
finally
{
    if (conn != null)
        conn.Dispose();
}


  • +1 코드 예제입니다. - Mitch Wheat
  • @AnthonyBlake 예외가 숨겨져 있지 않습니다. 예외가 발생하면 finally를 실행 한 다음 예외를 호출 스택 위로 전파합니다. - Adam Houldsworth
  • 엣지 케이스의 경우, 프로세스가 종료되면 (예 : 작업 관리자에서 "프로세스 종료"또는 정전 등으로) 마침내 실행되지 않습니다. - Nuffin
  • finally 스테이트먼트가 언제 발동하지 않을지에 대한 더 자세한 정보 - 프로세스가 종료되었을 때뿐만 아니라 :stackoverflow.com/questions/111597/… - Paddy
  • 또 다른 명백한 경우모든finally 블록의 중간에서 오류가 발생하면 finally가 실행됩니다. - Ben Hocking

5

using동등하다try-finally. 당신은try-finally내부 청소를하고 싶을 때.finally예외에 대해서는 상관하지 않습니다.

그만큼최선의 접근법될거야

try
{
   using(resource)
   {
       //Do something here
   }   
}catch(Exception)
{
     //Handle Error
}

그렇게함으로써 불리는 청소까지using실패하면 코드가 실패하지 않습니다.

다음과 같은 몇 가지 조건이 있습니다.finally사형 당하지 않을거야.

  • 어떤 것이 있으면StackOverflowException또는ExecutingEngineException.
  • 프로세스가 외부 소스에서 종료됩니다.

희망이 당신의 의심에 대한 답변.


2

예를 들어 try 블록에서 작성하여 사용하는 관리되지 않는 리소스가있는 경우 finally 블록을 사용하여 리소스를 해제 할 수 있습니다. finally 블록은 try 블록에서 발생하는 상황 (예 : 예외)에도 불구하고 항상 실행됩니다.

예 : lock (x) 문은 실제로 다음과 같습니다.

System.Threading.Monitor.Enter(x); 
try { ... } 
finally 
{ 
    System.Threading.Monitor.Exit(x); 
} 

finally 블록은 항상 독점 잠금이 해제되도록 호출됩니다.


2

코드를 사용한 좋은 설명 :

void MyMethod1()
{
    try
    {
        MyMethod2();
        MyMethod3();
    }
    catch(Exception e)
    {
        //do something with the exception
    }
}


void MyMethod2()
{
    try
    {
        //perform actions that need cleaning up
    }
    finally
    {
        //clean up
    }
}


void MyMethod3()
{
    //do something
}

MyMethod2 또는 MyMethod3이 예외를 throw하면 MyMethod1에 의해 catch됩니다. 그러나 MyMethod2의 코드는 정리 코드를 실행해야합니다. 예외가 MyMethod1에 전달되기 전에 데이터베이스 연결을 닫습니다.

http://forums.asp.net/t/1092267.aspx?Try+without+Catch+but+with+finally+doesn+t+throw+error+Why+no+syntax+error+


  • 이 & # 39; 청소 & # 39; saveLogFile ()이 될 수 있는데, 나는 종종 프로그램의 맨 끝에 넣고 싶다. - Vincent

1

finally 블록이 필요합니다. 어떤 예외 (있는 경우)가 잡히거나 아무 것도 잡히지 않아도 블록이 종료되기 전에 일부 코드를 실행하려고 할 때 필요합니다. 예를 들어 열린 파일을 닫을 수 있습니다.

참고 사항try-finally


1

try / finally : 예외를 처리하고 싶지 않지만 호출 된 코드에 의해 예외가 throw되는지 여부에 관계없이 일부 동작이 발생하도록하려는 경우.


1

다음 링크를 살펴보십시오.https://softwareengineering.stackexchange.com/questions/131397/why-use-try-finally-without-a-catch-clause

이는 응용 프로그램의 아키텍처와 블록에서 수행하는 작업에 따라 다릅니다.


1

try를 마지막으로 사용하고자 할 때가 있습니다 : 일반적으로 using 문을 사용할 때, 리플렉션으로 메소드를 호출하기 때문에 사용할 수없는 경우입니다.

이것은 작동하지 않을 것이다.

using (objMsg  =  Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("omApp.MessagingBO")))
{

}

대신에

           object objMsg = null;
            try
            {
                objMsg
                   = Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("myAssembly.objBO"));

                strResponse = (string)objMsg.GetType().InvokeMember("MyMethod", BindingFlags.Public
                        | BindingFlags.Instance | BindingFlags.InvokeMethod, null, objMsg,
                        new object[] { vxmlRequest.OuterXml });
            }               
            finally
            {
                if (objMsg!=null)
                    ((IDisposable)objMsg).Dispose();
            }


0

나는 C #에 대해 아무 것도 모른다. 그러나 당신이 try-finally로 할 수있는 모든 것, 당신은 더 우아하게 할 수있는 것으로 보인다.using 문. C ++에는 마침내RAII의 결과.


0

여기 내가 항상 사용하는 유스 케이스가있다.

int? x; //note the nullable type here!
try
{
    x = int.Parse(someString);
}
catch { } //don't care, let it just be null


0

1. 우리는 캐치없이 try 블록을 사용할 수 있지만 catch / finally를 사용해야합니다. 그들 중 하나. 2. 우리는 단지 블록을 시도 할 수 없습니다.

연결된 질문


관련된 질문

최근 질문