2009-09-03 8 views
61

이것은 내 initial question의 후속 조치이며, 필자의 연구 결과를 제시하고 수정, 아이디어 및 통찰력을 요구하고자합니다. 내 연구 결과 (또는 오히려 해석)는 이전 질문에 대한 사람들의 대답에서 왔으며 MSDN .NET 3.5 설명서를 읽고 .NET 3.5 코드를 디버깅했습니다. 응용 프로그램이 종료 될 때이를 탐지하는 방법을 궁금해하는 사람에게 이것이 유용 할 수 있기를 바랍니다.응용 프로그램이 종료 될 때 감지하는 방법?

이벤트 :

  • System.AppDomain.CurrentDomain.ProcessExit : 제기 할 때 프로세스가 종료, 예를 들어, 기본값 인 AppDomain 이후의 모든 것은 언로드되었습니다 [총 실행 시간은 단 3 초로 제한됩니다!]. WPF의 경우 System.Windows.Application.Exit을 대신 사용하십시오. Windows Forms의 경우 기본 방법으로 Application.Run(...) 뒤에 코드를 실행하십시오.

  • System.AppDomain.CurrentDomain.DomainUnload : 기본값 AppDomain 이외의 AppDomain이 언로드 될 때 발생합니다. 단위 테스트 프레임 워크 (TestDriven.NET이있는 MbUnit)로 클래스를 실행할 때.

  • System.AppDomain.CurrentDomain.UnhandledException

  • 은 :. 기본 AppDomain으로 처리하는 경우 (:)이 스레드의 시작이 의미, 이것은 포괄 모든 처리되지 않은 예외로 사용할 수있는 AppDomain 상관없이, 어떤 스레드에서 처리되지 않은 예외 발생하지.

  • System.Windows.Application.Exit : WPF 응용 프로그램 (기본값 : AppDomain)이 정상적으로 종료 될 때 발생합니다. 이를 활용하려면 System.Windows.Application.OnExit을 재정의하십시오.

  • 종결 자 (C#의 소멸자) : 가비지 수집기가 관리되지 않는 리소스를 해제 할 때 실행됩니다. [총 실행 시간은 제한되어 있습니다!] 이벤트의

주문 :

WPF 응용 프로그램 : 우아한 종료

  1. System.Windows.Application.Exit
  2. System.AppDomain.CurrentDomain.ProcessExit
  3. 종료 자

WPF 응용 프로그램 : 처리되지 않은 예외

  1. System.AppDomain.CurrentDomain.UnhandledException

MbUnit에 TestDriven.NET 내에서 실행 : 통과 시험 (정상 종료)

  1. System.AppDomain.CurrentDomain.DomainUnload
  2. 종료 자

MbUnit이 TestDriven 내에서 실행됩니다.

  • 내 해석/연구 결과가 올바른 위치 : NET :

    1. AppDomain.CurrentDomain.DomainUnload
    2. 종료 자

    질문 (처리되지 않은 예외가 MbUnit에 의해 처리됩니다) 실패 테스트?

  • 을 삭제 한 자세한 정보를 알고 계십니까? 예 : 파이널 라이저의 실행 시간은 총 입니까?
  • 알고 계신 다른 아이디어/ 아이디어를 알고 계신가요?
  • 다른 애플리케이션에서 발생하는 이벤트 및 순서는 무엇입니까? Windows Forms, 웹 서비스, ASP.NET 웹 사이트 등?

답변

7

은 사용자가 로그 오프하거나 종료 할 때 때 호출되는 또한 Application.SessionEnding (반전 조금이 질문입니다) 거기에 ssg31415926의 질문/대답하라는 메시지. Exit 이벤트 전에 호출됩니다.

+0

그냥 참고 참고/:이 닷넷 3.0 이상에서만 사용할 수 있습니다, 당신이 사용하는 System.Core.dll에 연결해야합니다 .NET 2.0에서 –

1
  1. 파이널 라이저 실행의 기본 제한 시간은 2 초입니다.
+0

당신은 그 소스를 가지고 있습니다, 그렇죠? – mbx

+1

@mbx http://msdn.microsoft.com/en-us/library/system.appdomain.processexit.aspx –

2

Dispatcher.BeginInvokeShutdown()이 호출되면 Application.Exit은 호출되지 않습니다.

1

당신은 쓰기 :

System.AppDomain.CurrentDomain.UnhandledException이 :. 기본 응용 프로그램 도메인 : 어떤 스레드에서 처리되지 않은 예외 발생으로 처리하는 경우에 상관없이 응용 프로그램 도메인이 스레드에서 시작되지 무엇을 (이 의미, 이것은 모든 처리되지 않은 예외에 대한 포괄적 인 것으로 사용될 수 있습니다.

나는 이것이 정확하다고 생각하지 않습니다.

using System; 
using System.Threading; 
using System.Threading.Tasks; 

namespace AppDomainTestingUnhandledException 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      AppDomain.CurrentDomain.UnhandledException += 
       (sender, eventArgs) => Console.WriteLine("Something went wrong! " + args); 

      var ad = AppDomain.CreateDomain("Test"); 

      var service = 
       (RunInAnotherDomain) 
       ad.CreateInstanceAndUnwrap(
        typeof(RunInAnotherDomain).Assembly.FullName, typeof(RunInAnotherDomain).FullName); 

      try 
      { 
       service.Start(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Crash: " + e.Message); 
      } 
      finally 
      { 
       AppDomain.Unload(ad); 
      } 
     } 
    } 

    class RunInAnotherDomain : MarshalByRefObject 
    { 
     public void Start() 
     { 
      Task.Run(
       () => 
        { 
         Thread.Sleep(1000); 
         Console.WriteLine("Uh oh!"); 
         throw new Exception("Oh no!"); 
        }); 

      while (true) 
      { 
       Console.WriteLine("Still running!"); 
       Thread.Sleep(300); 
      } 
     } 
    } 
} 

는 지금까지 내가 말할 수있는 UnhandledException 처리기가 호출되지 않습니다, 그리고 (디버거에서 실행하는 경우 또는 NAG) 스레드는 자동으로 충돌합니다 : 다음 코드를 사용해보십시오.

+0

그 라인도 분명하지 않습니다. 어쩌면 @ user65199는 * 이벤트 *가 "기본 AppDomain에서 처리되는"경우를 의미합니다. 예외가 잡히면 분명히 UnhandledException 이벤트가 발생하지 않습니다. 이 이벤트는 다른 AppDomain에서 실제로 시작된 스레드에서 처리되지 않은 예외 (기본 AppDomain에서 시작하는 예제가 아닌)의 경우에도 기본 AppDomain에서만 발생합니까? 나는 그것이 그가 얻고있는 것일지도 모른다라고 생각한다. 그러나 나는 그것이 규칙인지 확실하게 기억하지 않고있다. –

0

그냥 기본 양식에 새로운 이벤트를 추가 :

private void frmMain_Load(object sender, EventArgs e) 
{ 
    Application.ApplicationExit += new EventHandler(this.WhenItStopsDoThis); 
} 

private void WhenItStopsDoThis(object sender, EventArgs e) 
{ 
    //Program ended. Do something here. 
} 
관련 문제