C# – 프로그램 종료하기

#1

윈도우는 마우스나 키보드 입력같은 사용자 이벤트를 Queue에 넣고
System.Windows.Forms.Application.Run 에서는 MessageLoop를 실행합니다.

Application.Exit() 실행시 MessageLoop안에서 호출되므로
기존 메시지를 모두 처리하고 정상적으로 종료하게 됩니다.

또한 Application.Exit()으로 종료 요청시 FormClosing 이벤트 핸들러를 실행하므로
Stream이나 IO 등을 종료하시면 되겠습니다.

#2

Message Loop를 모두 처리하지 않고, 현재 thread를 종료후 모든 창을 닫습니다.
Exit()와의 중요한 차이점은 FormClosing 을 호출하지 않는점입니다.
System.Windows.Forms.CloseReason을 보시면
Application은 다양한 이유로 종료가 될 수 있는데
상황에 따라 FormClosing에서 thread의 종료 처리등을 해주어야 하지만
ExitThread()에서는 이를 수행할 수 없게됩니다.

Environment.Exit(0) 역시 Process와 모든 Thread를 그냥 죽여버리고 종료로 진입하며,
OS에 exitCode로 0(정상종료)를 리턴합니다.
참고 : http://www.hiteksoftware.com/mize/Knowledge/articles/049.htm

제 기억에 이 코드는 프로세스가 좀비가 되었을때 사용했었는데요..
Process를 강제로 죽이고 (이때 관련된 Thread도 죽겠죠), OS에게는 정상적으로 종료됐다고 뻥치는 코드입니다.
이것보다는 좀비가 되지 않도록 부모/자식 프로세스간의 종료처리를 명확히 해주고
Application.Exit()로 종료하는게 더 좋을듯합니다.

#3

그대도 안죽으면 강제로Process Kill 하는 방법도 있습니다.

또는

이건 뭐.. 코드를 보시다시피 Application과 관련된 프로세스들을 모두 찾아서 kill 해주는 거죠..
뒷처리 없이 확실히 죽기는 합니다.. -_-;

Notice

  • 이 저작물은 크리에이티브 커먼즈 저작자표시-비영리-변경금지 2.0 대한민국 라이선스에 따라 이용할 수 있습니다. 크리에이티브 커먼즈 라이선스
  • 저작권과 관련된 파일요청 및 작업요청을 받지 않습니다.
  • 댓글에 대한 답변은 늦을 수도 있습니다.
  • 13 댓글

    1. 행인 응답

      진짜 프로그래밍 하는 사람이라면 2번, 3번과 같은 코드를 보면 코웃음을 칠겁니다

      • kimstar 응답

        좋은 지적 감사합니다.
        2,3번의 경우 정상적으로 Process와 Thread를 종료 처리하지 못할때 사용했던 방법이므로 별로 좋은 방법은 아니네요..
        후임에게 생명주기를 설명하면서 사용했던 코드인데..
        제가 아직 진짜 프로그래머가 아니라서 설명하는 내공이 부족했던 모양입니다.
        부가 설명 달도록 하겠습니다. ^^

      • 응답

        왜 코웃음을 치게 될 지는 일언반구 하나 없네.
        정작 본인도 구글링으로 어느 키워드를 통해 들어오셨을텐데 정보 제공에 감사하지는 못할 망정 ‘진짜 프로그래머’ 운운하며 꼰대질하는 모습이 낯 뜨겁네요..^^

        • kimstar 글쓴이응답

          답변이 늦었습니다.
          온라인 상에는 여러 분류의 사람들이 있어서 그려려니 합니다.
          댓글 감사합니다. ^^

      • 김케이 응답

        행인님아 ? 같은 프로그래머로써 님 객기부리러 온건지 똥부심잡고 온건지 모르겠는데 부끄럽게좀 만들지 맙시다.
        어디 회사인지는 모르겠는데 참 프로그래머 교육 그지같이 시키나보네

    2. 질문 응답

      저기요 Application.Exit()을 이용하지 않고 정상적이지 않은 방법으로 종료시키면 머가 안좋나요?ㅇㅅㅇ

      • kimstar 응답

        정상적으로 프로그램을 종료할 수 없다는 것 자체가 프로그램에 오류가 있다는 증거인듯합니다.
        특히 IDiopose()를 상속받는 놈들은 using문 안에서 로직을 수행후 빠져나올때 Dispose()를 수행하면서 framework가 관리할 수 없는 자원을 해제하는 동작들을 하는데요.
        예를 들어 DB를 연결하여 사용중에 비정상 종료하게되면 서버쪽에서는 Connection이 유지된것으로 생각하고 있고, 최대 Connection 갯수를 제한한다면 다른 사용자의 접속시 문제가 될 수 있겠죠.

    3. 필승 응답

      제 프로그램에서는

      FormClosed 에서는 return;
      FormClosing 에서는 e.Calcel 처리한후 this.Hide 를 호출합니다.

      이유는 폼 우상단의 X 버튼을 실수로 눌러서 프로그램이 종료되는것을 방지하기 위함이고요.

      혹시 이 상태에서 특정 시각에 매일 Application.Restart 를 호출하여 프로그램을 재시작 하려고 할 때 FormClosing, FormClosed 에서 처리하는 내용 때문에 정상적으로 재시작이 되지 않거나 오류가 발생할 가능성이 있을까요?

      현재의 구조에서는 오류가 발생하는데 의심되는 부분이 FormClosing, FormClosed인 상황이라 그렇습니다.

      그리고 X버튼을 누르면 this.Hide가 수행되고 Application.Restart 호출시에는 프로그램이 정상적으로 종료되었다가 재실행되도록 하려면 어떻게 해야 할까요?

      • kimstar 글쓴이응답

        제가 Visual Studio가 없어서 테스트는 못해봤는데요..
        x버튼으로 종료 방지는 FormClosing 에서 e.Cancel=true; 정도면 될듯하고,
        특정시간에 winform을 활성화 할때는
        Form.Show() / Control.Focus() / this.WindowState = FormWindowState.Normal
        정도로 테스트 해보시면 될듯합니다.
        비슷한 예제가 http://kimstar.kr/7723/ 에 있으니 decompile 하여 보시면 도움이 될듯합니다.
        Winform 이벤트 순서도 참고하시구요.
        https://msdn.microsoft.com/ko-kr/library/86faxx0d(v=vs.110).aspx

    4. 김동환 응답

      우와 6년이 지난 지금도 댓글을 달아주고 계시다니 대단하신거 같아요!! 댓글 정말 안쓰는데 엄청 대단한거 같아서 글 남겨요~^^ 많이 배우고 갑니다.

      • kimstar 글쓴이응답

        이 글이 벌써 9년전 글이네요.
        C#의 발전 속도가 굉장히 빠른데다가, 지금은 C#에서 손 놓은지 꽤 되어서.. 지금도 유용한 내용인지 모르겠네요.
        9년전 당시에는 이런 정보가 있었구나 정도의 느낌으로 참고하여 주셨으면 합니다.
        감사합니다.

    댓글 남기기