Silverlight 1.1 바로 시작하기

디버깅과 예외 처리
준비 사항
Silverlight 개발의 기초에서 개발에 필요한 도구와 기술에 대해 설명하고 있습니다.
이벤트 핸들링에서 개체의 이벤트를 처리하는 방법에 대해 설명하고 있습니다.
커스텀 컨트롤에서 개발 프로젝트에 테스트 프로젝트를 추가하는 방법을 소개하고 있습니다.

기본적으로 Visual Studio IDE를 사용한 .Net 프로그래밍 및 디버깅 방법과 유사하므로 Visual Studio IDE를 사용한 보다 전문적인 디버깅은 Visual Studio의 디버깅을 참고하십시오. 이 글에서는 간단한 기법만을 소개합니다.

또한 ASP.NET 프로젝트와 IIS에 대한 언급도 나옵니다. 이 부분은 지금 곧 사용하지 않는다면 특별한 사전 지식은 필요 없습니다.

매니지드 코드 디버깅

일반적인 브레이크 포인트를 사용한 디버깅
매니지드 코드의 디버깅은 일반적인 .Net 프로그래밍에서의 그것과 동일합니다. 가장 기본적인 디버깅 방법으로 브레이크 포인트를 걸고 런타임에 해당 코드가 실행되기 직전에 코드의 실행을 멈추고 콜스택이나 멤버 변수 등의 값을 살펴볼 수 있습니다.

우선 매니지드 코드 디버깅 예제를 위해 새 프로젝트를 생성하고 일부러 틀린 코드를 넣어보겠습니다.
Howto:4-1 새 프로젝트에 잘못된 코드 작성하기
1. 새 프로젝트를 생성합니다. (프로젝트를 생성하는 방법은 Silverlight 개발의 기초를 참고하십시오.)
2. Page.xaml.cs의 Page 클래스에 다음과 같은 멤버 함수를 작성하고 Page_Loaded에서 해당 함수를 호출합니다.
C#
private void WrongMethod()
{
    TextBlock tb = new TextBlock();
    Run run = new Run();
    run.Text = "Test text";
    tb.Inlines.Add(run);
    this.Children.Add(tb);
}

위의 코드를 언뜻 보면 새 TextBlock 개체를 생성하고 TextBlock에 Run 텍스트를 하나 추가한 후 TextBlock을 페이지의 자식 개체로 추가하는 정상적인 코드처럼 보입니다. 아마도 개발자는 화면에 Test text 란 메시지가 출력되길 기대하고 있을 것입니다.

하지만 F5를 눌러 위의 코드를 디버그 모드로 실행해보면 화면에는 아무것도 나오지 않으며 다만 Output 창에는 예외가 발생했다는 메시지가 보입니다.


문제가 발생하는 시점을 찾기 위해 브레이크 포인트를 걸고 차근차근 진행해 보겠습니다.
Howto:4-2 브레이크 포인트 걸고 진행하기
1. 어디에서 문제가 생겼는지 확실치 않으므로 처음부터 브레이크 포인트를 설정합니다. 첫 문장인 TextBlock tb = new TextBlock() 코드에 커서를 맞추고 F9를 누르거나 해당 라인의 제일 왼쪽의 회색 공간을 클릭하여 브레이크 포인트를 설정합니다.


2. F5를 눌러 디버그 모드로 실행하면 다음과 같이 브레이크 포인트에서 코드 실행이 멈춥니다.


3. F10을 눌러 한 라인 단위로 진행합니다. (※노트: 함수 내부까지 들어가서 진행하려면 F11을 눌러 진행합니다.)

4. 아마도 tb.Inlines.Add(run); 문장을 진행하면 Output 창에 예외가 발생하였다는 메시지와 함께 디버깅이 중지되고 미완성된 페이지가 브라우저에 나타날 것입니다.

5. Shift + F5를 누르거나 디버깅 중인 브라우저를 닫아 디버깅 모드를 완전히 종료합니다.

6. 4번 과정을 실행하는 중 예외가 발생하였으므로 이 부분의 코드가 잘못되었다는 것을 알 수 있습니다. 또한 예외 메시지를 살펴 보면 [A first chance exception of type 'System.NullReferenceException' occurred in DebugManagedCode] 즉, 예외의 종류가 System.NullReferenceException임을 알 수 있고 자연스럽게 null을 참조하여 발생한 문제라는 것도 예상할 수 있습니다.

7. 다시 한번 디버깅을 진행하여 주의 깊게 진행하고 4번 과정에서 진행하지 않고 멈춰서 tb.Inlines 부분에 마우스 커서를 맞추면 다음과 같이 상세 정보를 볼 수 있습니다. 예상대로 tb.Inlines 멤버가 null을 참조하고 있으며 따라서 Inlines의 멤버 메소드인 .Add를 접근할 수 없음을 알 수 있습니다.
 

위의 시나리오는 비교적 간단하고 사소한 실수이지만 코드를 작성할 때 빈번하게 발생하는 문제이기도 합니다. 보통 코드를 작성하고 최초로 테스트 할 때에는 위와 같이 새로 작성한 코드에 브레이크 포인트를 설정하여 한 라인씩 진행하면서 코드가 예측한대로 작동하는지 검사하곤 합니다.

Visual Studio IDE는 디버그 모드상에서 어떤 개체에 대해 매우 직관적이고 상세한 정보를 실시간으로 볼 수 있는 인터페이스를 제공하고 있습니다. 각 개체는 자신의 멤버 뿐만 아니라 자신의 상위 개체에 대한 정보도 볼 수 있습니다.

브레이크 상태에서 코드를 직접 실행하기
브레이크가 걸린 상태에서 IDE에는 직접 실행 창(Immediate Window)이 나타납니다. 이 직접 실행 창에서는 현재 코드 상태에서 멤버의 값을 변경하거나 읽어오는 등 즉시 코드를 실행할 수 있습니다. 특히 임의의 식(expression)을 테스트 해볼 수도 있어서 디버깅에 매우 유용한 툴입니다.

Howto:4-3 직접 실행 창에서 디버깅 하기
1. 이전 예제를 디버깅 모드로 실행하고 브레이크 상태를 만든 후 문제의 코드까지 진행합니다. IDE의 하단에서 직접 실행 창(Immediate Window) 탭을 찾아 엽니다.

2. 직접 실행 창에 다음과 같이 입력하고 엔터를 눌러 tb.Inlines의 값을 확인해 봅니다.
Immediate Window
? tb.Inlines.ToString();


tb.Inlines가 null임을 확인할 수 있습니다. 여기에서 '?'는 직접 실행 창에 그 결과를 출력하라는 의미입니다.

3. 직접 실행 창에 다음과 같이 입력하고 엔터를 눌러 tb.Inlines의 새 인스턴스를 할당해 봅니다.
Immediate Window
tb.Inlines = new Inlines();



4. 개체 참조가 변경되었는지 확인하기 위해 다시 한번 tb.Inlines의 내용을 출력해봅니다.


5. F5를 눌러 코드를 계속 진행합니다. 아까와는 다르게 예외가 발생하지 않고 정상적인 출력이 된 것을 확인할 수 있습니다.


직접 실행 창을 사용하면 런타임 도중에 문제가 생겼다고 예상되는 지점에서 직접 코드를 테스트해볼 수 있습니다. 여기에서 이미 작성된 코드 뿐만 아니라 위의 예제와 같이 new 연산자 등을 통해 개체의 새 인스턴스를 생성하는 것도 가능하며 코드와 전혀 관계 없는 수식 등도 사용할 수 있습니다.

예외 처리
브레이크 포인트와 직접 실행 창을 사용한 디버깅은 개발 초기에는 문제점을 찾기에 매우 유용하지만 애플리케이션이 배포되고 난 후에는 전혀 도움이 되지 않습니다. 애플리케이션은 미처 수정하지 못한 문제점이 있기 마련이며 코드가 완벽하더라도 외부 환경적인 요인으로 인해 문제가 발생할 수도 있습니다.

예를 들어, 외부 리소스 XAML 파일의 스트림을 읽어오는 코드를 생각해보면 이 XAML 파일은 외부 컨텐츠이므로 해당 경로에 존재하지 않을 수도 있을 것입니다. 이렇게 동적으로 상태가 변경될 수 있는 가능성이 있는 코드는 반드시 예외 처리를 할 필요가 있으며 Silverlight 매니지드 코드에서는 전통적인 try~catch~finally문을 지원합니다.
Howto:4-4 예외가 발생할 수 있는 코드를 위한 try~catch 예제
1. Page.xaml.cs에 다음과 같이 System.IO 네임스페이스를 추가합니다.
C#
using System.IO;

2. Page 클래스에 다음과 같은 멤버 메소드를 작성하고 Page_Loaded에서 해당 메소드를 호출하는 코드를 추가하고 이전 예제인 WrongMethod() 호출은 주석처리 합니다.
C#
private void ExceptionalMethod()
{
    StreamReader sr = null;
    try
    {
        sr = new StreamReader("test.xaml");
        Brush dynamicBrush = (Brush)XamlReader.Load(sr.ReadToEnd());
        sr.Close();
    }
    catch (Exception ex)
    {
        string err = ex.Message;
    }
}

3. 프로젝트 폴더에 test.xaml이란 파일은 존재하지 않으므로 예외가 발생하고 catch 될 것을 예상할 수 있습니다. string err = ex.Message; 문장에 브레이크 포인트를 설정하고 F5를 눌러 프로젝트를 디버깅 모드로 실행해 봅니다.

4. IDE상의 직접 접근과 직접 실행 창 등을 통해 예외 정보 개체인 ex를 통해 예외의 정보에 접근할 수 있습니다.

코드에서 예외가 발생하면 그 다음 문장은 실행되지 않고 코드가 중지되어버리기 때문에 웹 애플리케이션의 관점에서 최악의 상황이라고 할 수 있습니다. 따라서 런타임 중 예외가 발생할 가능성이 있는 코드는 반드시 위와 같은 try~catch 문을 사용하여 예외가 발생했을 때 애플리케이션이 그냥 중지되어버리지 않도록 처리할 필요가 있습니다.

브레이크 포인트를 걸지 않고 정보 출력하기
매우 빈번하게 진행되는 코드의 디버깅을 브레이크 포인트로 한 줄씩 실행한다는 것은 너무나도 소모적인 일입니다. 보다 효율적인 디버깅을 위해 Silverlight는 System.Diagnostics 네임스페이스에 포함된 Debug 클래스를 제공합니다.


이 클래스는 디버깅 도중 브레이크 포인트를 걸지 않고도 Output 창에 문자열을 출력할 수 있는 WriteLine 메소드를 지원하며 WriteLine 메소드는 콘솔 애플리케이션의 Console.WriteLine 메소드와 동일한 사용법을 가졌습니다.
노트
아쉽게도, 매우 강력한 디버깅 도구인 Debug.Assert는 현재 제대로 작동하지 않는 것으로 보입니다. Assert는 코드의 전제 조건을 강제하고 조건이 실패하는 경우 코드의 실행을 멈추고 지정한 메시지를 출력하는 역할을 수행하는 메소드입니다. 하지만 Silverlight 1.1 Alpha(2007.5 CTP) 현재는 Assert에 어떤 조건을 걸어도 별도의 리액션이 발생하지 않습니다.

Howto:4-5 Debug.WriteLine 메소드
1. Page.xaml.cs에 다음과 같이 System.Diagnostics 네임스페이스를 추가합니다.
C#
using System.Diagnostics;

2. Page 클래스에 다음과 같은 멤버 메소드를 작성하고 Page_Loaded에서 해당 메소드를 호출하는 코드를 추가하고 이전의 두 예제 메소드는 주석처리 합니다.
C#
private void OutputMethod()
{
    int sum = 0;
    for (int i = 1; i <= 100; ++i)
    {
        sum += i;
        Debug.WriteLine("i = {0}, sum = {1}", i, sum);
    }
    Debug.WriteLine("Total = {0}", sum);
}

3. F5를 눌러 실행합니다. IDE의 Output 창에 다음과 같이 출력되었음을 확인할 수 있습니다.

지금까지 테스트했던 프로젝트를 첨부하였습니다.
DebugManagedCode.zip

매니지드 코드 디버깅



웹 프로젝트와 Silverlight 프로젝트를 함께 디버깅

Silverlight는 JavaScript를 사용하여 HTML 페이지에 호스트되는 클라이언트 사이드 애플리케이션이기 때문에 서버 사이드는 어떤 언어를 사용하여도 상관 없습니다. 하지만 Silverlight 컨트롤을 ASP.NET 페이지에 호스팅하도록 개발한다면 하나의 개발환경과 CLR을 통해 제공되는 일관된 언어 사용의 장점을 얻을 수 있을 것입니다.

이때 Silverlight 컨트롤이 자신을 호스팅하는 ASP.NET 페이지와 상호작용이 많다면 ASP.NET 페이지와 Silverlight 컨트롤의 코드를 함께 디버깅할 수 있으면 편리할 뿐더러 생산성도 대폭 향상될 것입니다.

이 절에서는 ASP.NET 웹 프로젝트에서 Silverlight 프로젝트를 추가하여 함께 디버깅하는 방법을 알아보겠습니다.

먼저 아주 간단하게 Hello Silverlight!를 출력하는 Silverlight 프로젝트를 하나 작성합니다. 이제 프로젝트 작성에 익숙해졌으리라 믿고 생성하는 방법은 생략하겠습니다. 프로젝트 이름은 HelloSilverlight라고 하겠습니다.
Howto:4-6 웹 프로젝트와 Silverlight 프로젝트를 링크하고 디버깅하는 방법
1. Visual Studio를 실행하고 메뉴에서 File->New->Project를 선택하거나 Ctrl+Shift+N을 눌러 새 프로젝트를 선택합니다.

2. Project Type에서 Visual C#->Web을 선택하고 Templates에서 ASP.NET Web Application을 선택한 후 프로젝트 이름을 MixedModeDebug라고 적고 [OK]를 누릅니다.
사용자 삽입 이미지


3. 솔루션 익스플로러의 솔루션 아이템에서 마우스 오른쪽 버튼을 누르고 Add->Existing Project를 선택합니다.


4. 미리 만들어둔 HelloSilverlight 프로젝트를 선택합니다. 솔루션 익스플로러에 이제 두개의 프로젝트가 포함될 것입니다.

5. 솔루션 익스플로러의 MixedModeDebug 웹 프로젝트에서 마우스 오른쪽 버튼을 누르고 Add Silverlight Link를 선택합니다.


6. 목록에 HelloSilverlight가 있을 것입니다. 선택하고 [OK]를 누릅니다.


7. 이 프로젝트를 위한 Silverlight 디버깅을 활성화 하겠냐고 묻는 창이 나옵니다. [예]를 누릅니다.
사용자 삽입 이미지

중요
이 설정은 스크립트 디버깅을 비활성화 상태로 설정합니다. Mixed-mode 디버깅을 사용하는 상태에서 매니지드 코드와 언매니지드 코드(스크립트)를 동시에 디버깅 할 수 없습니다.

8. 다음과 같이 MixedModeDebug 웹 프로젝트에 ClientBin과 Page.xaml 파일이 복사되었음을 확인할 수 있습니다.


9. Page.xaml을 ASP 페이지로 로드하기 위해 Silverlight.js와 createSilverlight 함수를 프로젝트로 추가합니다. 실제 프로젝트에서 Silverlight.js는 아마 웹서버의 공용 include 폴더에 위치할 것이며 createSilverlight 함수는 각 XAML 파일마다 하나씩 존재할 것입니다. 여기에서는 빠른 진행을 위해 HelloSilverlight 프로젝트의 Silverlight.js와 createSilverlight 함수가 포함된 TestPage.html.js 파일을 프로젝트로 추가하고 MixedModeDebug 웹 프로젝트의 Default.aspx에 위 스크립트 파일들을 include하고 Page.xaml을 로드할 것입니다.

솔루션 익스플로러의 MixedModeDebug 웹 프로젝트에서 마우스 오른쪽 버튼을 누르고 Add Existing Item을 선택하고 HelloSilverlight 프로젝트의 Silverlight.js 파일과 TestPage.html.js 파일을 선택합니다.



10. 다음과 같이 MixedModeDebug 웹 프로젝트에 해당 파일이 복사되었음을 확인할 수 있습니다.


11. HelloSilverlight 프로젝트의 TestPage.html 파일을 열어 스크립트를 include 하는 부분과 XAML을 로드하는 HTML 코드를 복사하여 MixedModeDebug 웹 프로젝트의 Default.aspx파일에 붙여넣습니다.
사용자 삽입 이미지


12. 양쪽 프로젝트에 모두 브레이크 포인트가 잡히는지 확인하기 위해 MixedModeDebug 웹 프로젝트의 Default.aspx.cs 파일에서 Page_Load 메소드에 브레이크 포인트를 설정하고 HelloSilverlight 프로젝트의 Page.xaml.cs 파일에 Page_Loaded 메소드에 브레이크 포인트를 설정합니다.


13. Ctrl+Shift+B 또는 F6을 눌러 솔루션을 빌드하고 F5를 눌러 디버깅 모드로 실행해 봅니다.
이때 Web.config 파일에 디버깅이 활성화되지 않았다는 메시지가 나올 것입니다. [Modify Web.config file to enable debugging.]을 선택하고 [OK]를 누릅니다.


14. 정상적인 경우 MixedModeDebug 웹 프로젝트의 Default.aspx.cs 파일에 먼저 브레이크가 걸리고 계속 진행하면 HelloSilverlight 프로젝트의 Page.xaml.cs 파일에 브레이크가 걸릴 것입니다.

웹 프로젝트에서 JavaScript 디버깅

앞서 소개한 디버깅 기법으로 웹 프로젝트와 Silverlight를 통합된 환경에서 디버깅할 수 있지만 이렇게 할 경우 다른 JavaScript 등의 스크립트 디버깅 기능은 사용할 수 없게 됩니다. 이 절에서는 이 전 절의 솔루션 상태에서 Silverlight 디버깅을 제거하고 JavaScript 디버깅을 하는 방법에 대해 알아보겠습니다.
Howto:4-7 웹 프로젝트에서 JavaScript 디버깅하는 방법
1. 먼저 인터넷 익스플로러를 디버깅 가능한 상태로 설정해야 합니다.
인터넷 익스플로러의 도구 메뉴에서 인터넷 옵션을 선택합니다.

2. 고급 탭에서 '스크립트 디버깅 사용 안 함(Internet Explorer)'의 체크를 해제합니다. 만약 다른 브라우저로도 디버깅하려면 '스크립트 디버깅 사용 안 함(기타)'의 체크도 해제합니다.

3. '모든 스크립트 오류에 관련된 알림 표시'를 체크합니다.

4. 'HTTP 오류 메시지 표시'의 체크를 해제합니다.

5. MixedModeDebug 웹 프로젝트의 Default.aspx의 body 태그에 테스트를 위해 다음과 같은 JavaScript 코드를 추가합니다.
JavaScript
<script type="text/javascript">
    var today = Date();
    alert(today.toString());
</script>

6. 솔루션 익스플로러의 MixedModeDebug 웹 프로젝트에서 마우스 오른쪽 버튼을 누르고 Properties를 선택하거나 Properties 항목을 더블 클릭합니다.

7. Web 탭의 Debuggers 섹션에서 Silverlight의 체크를 해제합니다.
사용자 삽입 이미지


8. 속성 패널을 닫고 5번 과정에서 추가한 JavaScript 코드에 브레이크 포인트를 추가합니다.

9. 솔루션을 빌드하고 F5를 눌러 디버깅 모드로 실행합니다.

10. 다음과 같이 JavaScript에서 브레이크가 걸리고 줄 단위 혹은 코드 단위 진행이 가능합니다.

여기까지 작성된 프로젝트를 첨부합니다.
MixedModeDebug.zip

MixedMode 디버깅과 JavaScript 디버깅



IIS를 사용한 디버깅

기본적으로 ASP.NET 페이지 프로젝트는 Visual Studio의 가상 웹서버를 통해 호스팅됩니다. 실제 프로젝트에서는 IIS와 연동을 통한 테스트를 직접 수행할 수 있습니다.
Howto:4-8 IIS를 사용한 디버깅
1. MixedModeDebug 웹 프로젝트에서 마우스 오른쪽 버튼을 누르고 Properties를 선택하거나 Properties 항목을 더블 클릭합니다.

2. Web 탭의 Servers 섹션에서 Use IIS Server를 체크합니다. 이 옵션은 반드시 IIS 서버가 사용 가능한 상태여야 합니다.

3. Create New Virtual Directory를 클릭하고 새로 생성할 디렉토리의 정보를 입력합니다.

4. 속성 패널을 닫고 모두 저장합니다.
이제 실제 IIS 서버를 사용하여 디버깅을 할 수 있습니다.

참고

Silverlight 공식 QuickStarts 참고:
http://silverlight.net/QuickStarts/Start/Debug.aspx

Visual Studio 디버깅 참고:
http://msdn2.microsoft.com/ko-kr/library/sc65sadd(VS.80).aspx
신고
Posted by gongdo


티스토리 툴바