성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>Windows Forms의 오류(Exception) 처리 방법에 대한 차이점 설명</h1> <p> 다음의 질문에 달린 덧글에,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 프로그램 비정상 종료 메시지 창 없애는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/3/0/4830'>http://www.sysnet.pe.kr/3/0/4830</a> </pre> <br /> 0으로 나누기 했을때의 메시지 창과 비정상 종료했을 때의 메시지 창 유형이 다르다고 나옵니다.<br /> <br /> 사실 이것은 0으로 나누기에 대한 문제가 아니라 Windows Forms이 제공하는 환경 위에서 오류가 발생했냐/안 했냐의 문제입니다. 예를 한번 들어 볼까요? ^^<br /> <br /> 간단하게 Windows Forms 위에 버튼을 하나 두고, 그 버튼 Click 이벤트에 다음의 코드를 넣어 실행해 봅니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > private void button1_Click(object sender, EventArgs e) { int a = 5; int b = 0; int c = a / b; } </pre> <br /> (버튼을 누르면, 당연히) 다음과 같은 오류 대화창이 뜨고,<br /> <br /> <img alt='error_handler_1.png' src='/SysWebRes/bbs/error_handler_1.png' /><br /> <br /> 이때 Visual Studio를 이용해 디버거를 붙여 콜 스택을 확인하면 그 이유를 조사할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) Unknown System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) Unknown System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) Unknown System.Windows.Forms.dll!System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form form) Unknown System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) Unknown System.Windows.Forms.dll!System.Windows.Forms.<span style='color: blue; font-weight: bold'>Form.ShowDialog</span>() Unknown System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.OnThreadException(System.Exception t) Unknown System.Windows.Forms.dll!System.Windows.Forms.Control.WndProcException(System.Exception e) Unknown <span style='color: blue; font-weight: bold'>System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnThreadException(System.Exception e) Unknown</span> System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Unknown </pre> <br /> 그럼, 대화창을 실제로 만드는 코드를 OnThreadException에서 찾아볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > internal void OnThreadException(Exception t) { if (!this.GetState(4)) { this.SetState(4, true); try { ...[생략]... else if (SystemInformation.UserInteractive) { <span style='color: blue; font-weight: bold'>ThreadExceptionDialog dialog = new ThreadExceptionDialog(t);</span> DialogResult oK = DialogResult.OK; IntSecurity.ModifyFocus.Assert(); try { <span style='color: blue; font-weight: bold'>oK = dialog.ShowDialog();</span> } ...[생략]... } return; Label_0084: ...[생략]... } finally { this.SetState(4, false); } } } </pre> <br /> 그리고 OnThreadException은 Windows 응용 프로그램의 필수 요소인 메시지 루프의 Win32 Message 처리 시 예외가 발생한 경우 수행된다는 것을 System.Windows.Forms.NativeWindow.Callback에서 찾아 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > private IntPtr Callback(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam) { Message m = Message.Create(hWnd, msg, wparam, lparam); <span style='color: blue; font-weight: bold'>try {</span>} if (this.weakThisPtr.IsAlive && (this.weakThisPtr.Target != null)) { <span style='color: blue; font-weight: bold'>this.WndProc(ref m);</span> } else { <span style='color: blue; font-weight: bold'>this.DefWndProc(ref m);</span> } <span style='color: blue; font-weight: bold'>} catch (Exception exception) { this.OnThreadException(exception); }</span> finally { if (msg == 130) { this.ReleaseHandle(false); } if (msg == NativeMethods.WM_UIUNSUBCLASS) { this.ReleaseHandle(true); } } return m.Result; } </pre> <br /> 따라서, Win32 Message 처리 도중 예외가 발생한다면 .NET Windows Forms에서 마련한 예외 창이 뜨게 됩니다.<br /> <br /> 그렇다면, 당연히 다른 곳에서 예외가 발생하면 Windows Forms도 처리를 할 수 없으므로 시스템에 넘어가게 됩니다. 그 결과로 나온 아래와 같은 형식의 창은 (디버거 설치 유무 등의 정보 등을 조사한 다음 적절한 사후 처리를 할 수 있도록) 운영체제가 담당하게 됩니다. 다음은 디버거가 설치된 시스템에서 운영체제가 띄우는 오류 보고 창입니다.<br /> <br /> <img alt='error_handler_2.png' src='/SysWebRes/bbs/error_handler_2.png' /><br /> <br /> 이를 테스트하고 싶다면 Windows Forms에 또 다른 버튼을 만들고 그 이벤트 핸들러에 다음과 같은 식으로 별도의 스레드를 이용해 처리를 맡겨 보면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > private void button2_Click(object sender, EventArgs e) { ThreadPool.QueueUserWorkItem((arg) => { int a = 5; int b = 0; int c = a / b; }, null); } </pre> <br /> 저 스레드에서는 Windows Forms의 Message Loop 처리 코드가 없기 때문에 예외가 발생하면 운영체제로 곧장 넘어가 비정상 종료를 하게 됩니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
7766
(왼쪽의 숫자를 입력해야 합니다.)