처리되지 않은 예외로 인해 ASP가 발생합니다. .NET Framework 예기치 않게 종료되는 NET 기반 애플리케이션

이 문서는 처리되지 않은 예외로 인해 ASP가 발생하는 문제를 resolve 데 도움이 됩니다. .NET Framework 예기치 않게 종료할 NET 기반 애플리케이션입니다.

원래 제품 버전: .NET Framework 4.5
원본 KB 번호: 911816

참고

이 문서는 Microsoft .NET Framework 2.0 이상 버전에 적용됩니다.

증상

ASP에서 처리되지 않은 예외가 throw되는 경우 .NET Framework 2.0 이상 버전에서 빌드된 NET 기반 애플리케이션은 예기치 않게 종료됩니다. 이 문제가 발생하면 문제를 이해해야 하는 예외 정보가 애플리케이션 로그에 기록되지 않습니다.

그러나 다음 예제와 유사한 이벤트 메시지는 시스템 로그에 기록될 수 있습니다. 또한 다음 예제와 유사한 이벤트 메시지가 애플리케이션 로그에 기록될 수 있습니다.

원인

이 문제는 처리되지 않은 예외에 대한 기본 정책이 .NET Framework 2.0 이상 버전에서 변경되었기 때문에 발생합니다. 기본적으로 처리되지 않은 예외에 대한 정책은 작업자 프로세스를 종료하는 것입니다.

.NET Framework 1.1 및 .NET Framework 1.0에서는 관리되는 스레드에서 처리되지 않은 예외가 무시되었습니다. 예외를 catch하기 위해 디버거를 연결하지 않으면 문제가 있다는 것을 깨닫지 못할 것입니다.

ASP.NET .NET Framework 2.0 이상 버전에서 처리되지 않은 예외에 대한 기본 정책을 사용합니다. 처리되지 않은 예외가 throw되면 ASP입니다. NET 기반 애플리케이션이 예기치 않게 종료됩니다.

이 동작은 요청 컨텍스트에서 발생하는 예외에는 적용되지 않습니다. 이러한 종류의 예외는 여전히 처리되고 개체에 HttpException 의해 래핑됩니다. 요청 컨텍스트에서 발생하는 예외로 인해 작업자 프로세스가 종료되지 않습니다. 그러나 타이머 스레드 또는 콜백 함수의 예외와 같이 요청 컨텍스트 외부에서 처리되지 않은 예외로 인해 작업자 프로세스가 종료됩니다.

해결 방법 1

예외 정보를 애플리케이션 로그에 기록하도록 개체의 IHttpModule 소스 코드를 수정합니다. 기록되는 정보에는 다음이 포함됩니다.

  • 예외가 발생한 가상 디렉터리 경로
  • 예외 이름
  • 메시지
  • 스택 추적

개체를 IHttpModule 수정하려면 다음 단계를 수행합니다.

참고

이 코드는 애플리케이션 로그에 이벤트 유형 오류ASP.NET 2.0.50727.0의 이벤트 원본 이 있는 메시지를 기록합니다. 모듈을 테스트하려면 메서드를 사용하여 처리되지 않은 예외를 ThreadPool.QueueUserWorkItem throw하는 메서드를 호출하는 ASP.NET 페이지를 요청합니다.

  1. 이름이 UnhandledExceptionModule.cs 파일에 다음 코드를 넣습니다.

    using System;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    using System.Web;
    
    namespace WebMonitor
    {
        public class UnhandledExceptionModule: IHttpModule
        {
    
            static int _unhandledExceptionCount = 0;
            static string _sourceName = null;
            static object _initLock = new object();
            static bool _initialized = false;
    
            public void Init(HttpApplication app)
            {
    
                // Do this one time for each AppDomain.
                if (!_initialized)
                {
                    lock (_initLock)
                    {
                        if (!_initialized)
                        {
                            string webenginePath = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(),
                            "webengine.dll");
    
                            if (!File.Exists(webenginePath))
                            {
                                throw new Exception(String.Format(CultureInfo.InvariantCulture,
                                                            "Failed to locate webengine.dll at '{0}'.
                                                            This module requires .NET Framework 2.0.",
                                                                  webenginePath));
                            }
    
                            FileVersionInfo ver = FileVersionInfo.GetVersionInfo(webenginePath);
                            _sourceName = string.Format(CultureInfo.InvariantCulture,
                             "ASP.NET {0}.{1}.{2}.0",
                                                        ver.FileMajorPart, ver.FileMinorPart,
                                                         ver.FileBuildPart);
    
                            if (!EventLog.SourceExists(_sourceName))
                            {
                                throw new Exception(String.Format(CultureInfo.InvariantCulture,
                                                            "There is no EventLog source named '{0}'.
                                                            This module requires .NET Framework 2.0.",
                                                                  _sourceName));
                            }
    
                            AppDomain.CurrentDomain.UnhandledException +=
                            new UnhandledExceptionEventHandler(OnUnhandledException);
    
                            _initialized = true;
                        }
                    }
                }
            }
    
            public void Dispose()
            {
            }
    
            void OnUnhandledException(object o, UnhandledExceptionEventArgs e)
            {
                // Let this occur one time for each AppDomain.
                if (Interlocked.Exchange(ref _unhandledExceptionCount, 1) != 0)
                    return;
    
                StringBuilder message = new StringBuilder("\r\n\r\nUnhandledException logged by
                UnhandledExceptionModule.dll:\r\n\r\nappId=");
    
                string appId = (string) AppDomain.CurrentDomain.GetData(".appId");
                if (appId != null)
                {
                    message.Append(appId);
                }
    
                Exception currentException = null;
                for (currentException = (Exception)e.ExceptionObject; currentException != null;
                currentException = currentException.InnerException)
                {
                    message.AppendFormat("\r\n\r\ntype={0}\r\n\r\nmessage={1}
                    \r\n\r\nstack=\r\n{2}\r\n\r\n",
                                         currentException.GetType().FullName,
                                         currentException.Message,
                                         currentException.StackTrace);
                }
    
                EventLog Log = new EventLog();
                Log.Source = _sourceName;
                Log.WriteEntry(message.ToString(), EventLogEntryType.Error);
            }
        }
    }
    
  2. UnhandledExceptionModule.cs 파일을 폴더에 저장합니다C:\Program Files\Microsoft Visual Studio 8\VC.

  3. Visual Studio 명령 프롬프트를 엽니다.

  4. 를 입력 sn.exe -k key.snk한 다음 Enter 키를 누릅니 .

  5. 를 입력 csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.cs한 다음 Enter 키를 누릅니 .

  6. 를 입력 gacutil.exe /if UnhandledExceptionModule.dll한 다음 Enter 키를 누릅니 .

  7. 를 입력 ngen install UnhandledExceptionModule.dll한 다음 Enter 키를 누릅니 .

  8. 를 입력 gacutil /l UnhandledExceptionModule한 다음 Enter 키를 눌러 UnhandledExceptionModule 파일의 강력한 이름을 표시합니다.

  9. ASP의 Web.config 파일에 다음 코드를 추가합니다. NET 기반 애플리케이션.

    <add name="UnhandledExceptionModule"
    type="WebMonitor.UnhandledExceptionModule, <strong name>" />
    

해결 방법 2

처리되지 않은 예외 정책을 .NET Framework 1.1 및 .NET Framework 1.0에서 발생하는 기본 동작으로 다시 변경합니다.

참고

기본 동작을 변경하지 않는 것이 좋습니다. 예외를 무시하면 애플리케이션이 리소스를 누수하고 잠금을 포기할 수 있습니다.

이 기본 동작을 사용하도록 설정하려면 다음 폴더에 있는 Aspnet.config 파일에 다음 코드를 추가합니다.
%WINDIR%\Microsoft.NET\Framework\v2.0.50727

<configuration>
     <runtime>
         <legacyUnhandledExceptionPolicy enabled="true" />
     </runtime>
</configuration>

상태

이것은 의도적으로 설계된 동작입니다.

추가 정보

.NET Framework 2.0의 변경 내용에 대한 자세한 내용은 .NET Framework 2.0의 주요 변경 내용을 참조하세요.