IT박스

C # "finally"블록이 항상 실행됩니까?

itboxs 2020. 11. 13. 07:56
반응형

C # "finally"블록이 항상 실행됩니까?


중복 가능성 :
Try 블록에 값을 반환하면 finally 문의 코드가 실행됩니까?

다음 코드 C # 코드를 고려하십시오. "finally"블록이 실행됩니까?

public void DoesThisExecute() {
   string ext = "xlsx";
   string message = string.Empty;
   try {
      switch (ext) {
         case "xls": message = "Great choice!"; break;
         case "csv": message = "Better choice!"; break;
         case "exe": message = "Do not try to break me!"; break;
         default:
            message = "You will not win!";
            return;
      }
   }
   catch (Exception) {
      // Handle an exception.
   }
   finally {
      MessageBox.Show(message);
   }
}

하,이 글을 쓰고 난 후 Visual Studio에서 직접 테스트 할 수 있다는 것을 깨달았습니다. 그러나 부담없이 답변 해주십시오!


예 :-) http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx


아니 그렇지 않아. 응용 프로그램이 아직 실행 중이면 항상 실행됩니다 ( 다른 사람과 마찬가지로 FastFail 예외 동안 MSDN 링크 제외 ). 블록의 try / catch 부분을 종료 할 때 실행됩니다.

응용 프로그램이 충돌하면 실행되지 않습니다. 프로세스 종료 명령 등을 통해 종료됩니다. 수동으로 롤백하는 것과 같이 절대적으로 실행될 것으로 예상하는 코드를 작성하면 자동으로 실행되기 때문입니다. 커밋하면 애플리케이션이 중단되기 전에 시나리오를 실행할 수 있습니다. 솔직히 이것은 외부 시나리오이지만 이러한 상황에서 주목하는 것이 중요합니다.


try진술 의 MSDN C # 사양에서 :

finally블록 의 문은 제어가 try문을 떠날 때 항상 실행됩니다 . 이는 전송 제어가 실행 한 결과, 정상적인 실행의 결과로서 발생하는지 사실 break, continue, goto, 또는 return, 또는 의견 예외 전파의 결과로 문을 try문.

출처

finally 블록이 실행되지 않는 경우가 있습니다.

  1. Environment.FailFast
  2. 잡을 수없는 예외 유형
  3. 정전

finally항상 실행되는 것은 전적으로 사실 이 아닙니다. Haacked의 답변참조하십시오 .

두 가지 가능성 :

  • StackOverflowException
  • ExecutingEngineException

더 이상 코드를 실행할 공간이 스택에 없기 때문에, finally 블록은 StackOverflowException이있을 때 실행되지 않습니다. 매우 드물게 발생하는 ExecutingEngineException이있을 때도 호출되지 않습니다.

실제로 모든 종류의 비동기 예외 (예 StackOverflowException: OutOfMemoryException,, ThreadAbortException)의 경우 finally블록 실행이 보장되지 않습니다.

그러나 이러한 예외는 일반적으로 복구 할 수없는 예외이며 대부분의 경우 프로세스는 어쨌든 종료됩니다.

실제로 현재 삭제 된 질문 에서 Brian Rasmussen이finally 설명한대로 실행되지 않는 다른 사례가 하나 이상 있습니다 .

내가 아는 다른 경우는 종료자가 예외를 던지는 경우입니다. 이 경우 프로세스도 즉시 종료되므로 보증이 적용되지 않습니다.

아래 코드는 문제를 보여줍니다.

static void Main(string[] args) {
   try {
      DisposableType d = new DisposableType();
      d.Dispose();
      d = null;
      GC.Collect();
      GC.WaitForPendingFinalizers();
   } catch {
      Console.WriteLine("catch");
   } finally {
      Console.WriteLine("finally");
   }
}

public class DisposableType : IDisposable {
   public void Dispose() {
   }

   ~DisposableType() {
      throw new NotImplementedException();
   }
}

신뢰할 수있는 try / catch / finally는 CER (Constrained Execution Region) 를 사용해야 합니다. 예는 MSDN에 의해 제공된다 :

[StructLayout(LayoutKind.Sequential)]
struct MyStruct
{
    public IntPtr m_outputHandle;
}

sealed class MySafeHandle : SafeHandle
{
    // Called by P/Invoke when returning SafeHandles
    public MySafeHandle()
        : base(IntPtr.Zero, true)
    {
    }

    public MySafeHandle AllocateHandle()
    {
        // Allocate SafeHandle first to avoid failure later.
        MySafeHandle sh = new MySafeHandle();

        RuntimeHelpers.PrepareConstrainedRegions();
        try { }
        finally
        {
            MyStruct myStruct = new MyStruct();
            NativeAllocateHandle(ref myStruct);
            sh.SetHandle(myStruct.m_outputHandle);
        }

        return sh;
    }
}

훌륭한 정보 출처는 다음 기사입니다.

신뢰성 모범 사례


MSDN try-finally에서 (C # 참조)

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


finally 블록은 다음 줄 사이에서 실행됩니다.

message = "You will not win!";
return;

Yes, under normal circumstances (as many others have pointed out).

The finally block is useful for cleaning up any resources allocated in the try block as well as running any code that must execute even if there is an exception. Control is always passed to the finally block regardless of how the try block exits.

Whereas catch is used to handle exceptions that occur in a statement block, finally is used to guarantee a statement block of code executes regardless of how the preceding try block is exited.

http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx


Yes, finally always executes, now whether or not the code in the finally block will cause an exception is a different story.


The right answer is Yes.

Try to debug your program and put a break point and watch as control still hits the finally block.


No it doesn't.

There's only a single way around it though and that is Environment.FailFast(). See http://msdn.microsoft.com/de-de/library/ms131100.aspx. In every other case it is guaranteed that finalizers get executed ;-)

The FailFast method writes the message string to the Windows Application event log, creates a dump of your application, and then terminates the current process. The message string is also included in error reporting to Microsoft.

Use the FailFast method instead of the Exit method to terminate your application if the state of your application is damaged beyond repair, and executing your application's try/finally blocks and finalizers will corrupt program resources.


Simple answer Yes. But there are some "exceptions" to the rule.

참고URL : https://stackoverflow.com/questions/3216046/does-the-c-sharp-finally-block-always-execute

반응형