오늘 소개하려는 Visual Studio 확장 기능은 멀티 타기팅 팩의 기능을 매우 적극적으로 활용하는 똑똑한 확장 기능이다. 실무에서 3.5세대 혹은 4세대 닷넷 프레임워크를 적극적으로 사용 중인 개발자들이 국내에도 많이 있을텐데 이 경우 숟한 고민에 부딪히게 되는 것 중에 하나는 다중 플랫폼을 지원해야 한다는 점이다. 대충 열거해봐도 세 가지 이상은 된다. ASP.NET, Windows Presentation Foundation, Silverlight, 경우에 따라서는 XNA Game Studio나 Windows Phone 7.1까지 생각해야 하는 셈이다.

물론 신경써서 세심하게 잘 프로그래밍할 수 있을만큼 노련하다면야 이런 도구가 굳이 필요하지는 않겠지만 사람이 하는 일인지라 신경쓸 것이 많아지면 자연스레 귀찮을 수 밖에 없고 실수도 어디선가는 꼭 나온다. 이런 불분명하고 애매한 상황을 도구를 통하여 정확하게 잡아낼 수 있다면 괜찮지 않을까? Microsoft 개발 팀이 이런 문제를 해결해 줄 명쾌한 답을 Visual Studio Gallery에 올려놓았으니 참고하기 바란다. 아래의 URL에서 다운로드할 수 있다.

http://visualstudiogallery.msdn.microsoft.com/b0e0b5e9-e138-410b-ad10-00cb3caf4981/

Portable Library Tools를 설치하면 Visual Studio에 새로운 프로젝트 템플릿이 C#과 Visual Basic .NET에 대하여 Windows 카테고리 아래에 아래 그림과 같이 나타날 것이다.


시험삼아 새 프로젝트를 한 번 만들어보자. 이름에서 알 수 있듯이 특별할 것이 없는 공통되는 코드를 묶기 위한 클래스 라이브러리 프로젝트로서 만들어지며 일상적으로 여러분의 코드를 추가할 수 있다. 그런데 정말 중요한 것은 프로젝트 속성 안에 들어있다. 프로젝트 속성을 열어보면 아래와 같이 재미있는 구성을 볼 수 있다.

목표로 하는 프레임워크를 이전처럼 하나만 선택하는 것이 아니라 하나 이상을 동시에 지정할 수 있다. 이는 다시 말해서 이들 프레임워크의 공통 분모만을 사용하여 클래스 라이브러리를 정확히 프로그래밍할 수 있도록 보증한다는 의미이다. 그리고 Change 버튼을 클릭하면 더 유용한 쓰임새를 찾을 수 있다.

Visual Studio와 함께 설치된 다른 멀티 타기팅 팩이 있을 경우 여기에 모두 열거되어 여러분이 선택할 수 있도록 할 수 있다. 프로젝트의 종류가 많고 정말 일반적이면서도 널리 쓰여야 할 클래스 라이브러리를 만들어야 한다면 여기서 선택을 어떻게 하는가에 따라서 사용할 수 있는 API가 자동으로 필터링된다. 만약 위에서 선택한 플랫폼에서 사용할 수 없는 API에 대한 내용이 발견되면 곧바로 빌드 오류로 나타나기 때문에 문제를 쉽게 찾아낼 수 있다. 그리고 여기서 선택한 대로 해당 프로젝트에서 레퍼런스로 추가할 수 있으므로 생산성도 높일 수 있다. 즉, 솔루션이나 프로젝트를 여러벌로 나눠 관리할 필요 없이 한 곳에서 모두 관리할 수 있다.

이 도구를 사용하기 위해서는 Visual Studio 2010 전체 버전이 필요하며 SP1이 설치되어있어야 한다. 그리고 다른 타기팅 팩이 필요하다면 아래 URL에서 추가적으로 설치할 수 있다. 타기팅 팩은 그 자체로 설치할 수 있는 것은 아니고 보통은 해당 플랫폼에 대한 SDK 안에 같이 수록된다는 점에 유의해야 한다.

http://go.microsoft.com/fwlink/?LinkID=153626

저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

최근 발표된 Windows Azure SDK 1.2에 추가된 Visual Studio 2010을 위한 IntelliTrace 기능은 여러모로 Windows Azure의 개발 과정과 시행 착오를 최소화할 수 있는 효과적인 도구입니다. 그렇지만 이 기능을 적용하기 위해서 필요한 요구 사양이 있는데 다음과 같습니다.

  • IntelliTrace는 Visual Studio 2010 Ultimate 이상의 버전에서만 사용이 가능합니다. (이 점이 IntelliTrace에 관해서 가장 많이 놓치게 되는 부분일것 같습니다.)
  • Visual Studio Tools for Windows Azure 1.2 버전에서만 가능합니다.
  • 64비트 버전의 OS에서만 사용이 가능합니다. (이 부분에 대한 설명이 충분하지 않았기 때문에 많은 착오가 있을 수 있습니다.)
  • IntelliTrace로 추적할 대상 Web Role - 또는 - Worker Role은 반드시 .NET Framework 4.0 기반으로 컴파일되어야 합니다.

Visual Studio 2010 Ultimate 버전을 설치하고, 최신 버전의 SDK와 Visual Studio Tools를 설치했음에도 불구하고 배포 시에 IntelliTrace 옵션이 활성화되지 않았던 경우에는 32비트 버전의 OS를 사용하고 있기 때문입니다. 이러한 경우, 아래의 Hotfix를 설치하여 문제를 해결하실 수 있습니다.

http://go.microsoft.com/fwlink/?LinkId=191542

다운로드 바로가기: http://code.msdn.microsoft.com/KB983301/Release/ProjectReleases.aspx?ReleaseId=4351

자료 출처: http://msdn.microsoft.com/en-us/library/ff683671.aspx

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

많은 Windows Azure Application 개발자들의 피드백을 수용한 최신 버전의 Windows Azure Tools for Visual Studio와 Windows Azure SDK가 새롭게 출시되었습니다. 이제 비로소 Visual Studio 2010의 모든 기능을 Windows Azure 개발에도 직접 활용할 수 있게 되었습니다.

Windows Azure SDK 1.2에서는 최근 발표된 .NET Framework 4.0 런타임을 내장한 Windows Azure OS 2010년 4월 버전에 대한 요구 사항을 모두 반영하고 있습니다. .NET Framework 4.0 기반의 응용프로그램을 작성 중이신 분들도 이제는 Windows Azure 환경 위에서 직접 응용프로그램을 호스팅할 수 있습니다. 그리고, Visual Studio 2010에서 새로 추가된 향상된 디버깅 기법인 IntelliTrace를 직접 지원하기 때문에 이전보다 더욱 쉬운 디버깅이 가능합니다.

다음은 Windows Azure Tools for Visual Studio 1.2의 변경 사항들입니다.

  • Visual Studio 2010 RTM 지원: Visual Studio 2010 RTM 버전을 지원합니다.
  • .NET Framework 4.0 지원: 이제는 .NET Framework 3.5와 4.0을 빌드 타겟으로 동시에 지정할 수 있습니다. 단, 4.0을 빌드 타겟으로 지정하게 되는 경우, Windows Azure OS의 이미지 중 2010년 초반의 일부 버전은 사용할 수 없습니다.
  • Cloud storage explorer 추가: 읽기 전용 기능이 지원되는 Windows Azure Table 및 BLOB 컨테이너 보기 프로그램이 서버 탐색기 패널을 통하여 제공됩니다. SQL Azure를 데이터베이스 목록에 추가하고 동시에 관리할 수 있어 편리합니다.
  • 통합 배포 환경: 솔루션 탐색기에서 Windows Azure 프로젝트를 오른쪽 버튼으로 클릭하여 'Publish' 메뉴를 클릭하면 이제는 직접 배포가 가능합니다. 이전 1.0 및 1.1 버전의 경우, CSPKG 파일과 CSCFG 파일이 생성된 디렉터리의 폴더가 Windows 탐색기에서 열리고, Windows Azure Portal Web Site가 웹 브라우저로 열렸기 때문에, 브라우저에서 로그인하고 여러 단계에 걸쳐서 배포할 파일을 찾아가야했기 때문에 Deploy 절차가 복잡했습니다.
  • 서비스 모니터링: 서비스의 상태를 웹 제어판이 아닌 "서버 탐색기"의 compute 노드에서 실시간으로 모니터링할 수 있습니다.
  • IntelliTrace 기능 지원: Visual Studio 2010을 사용하는 경우, IntelliTrace 기능을 Windows Azure 서비스에 배포한 이후에 "직접" 사용할 수 있습니다. 이 기능은 앞에서 설명한 통합 배포 환경의 일부로 동작하며, 배포가 끝난 이후에 자동으로 이 기능이 시작되어 서비스 모니터링과 함께 실시간으로 로그가 모니터링됩니다.

그간 Windows Azure 기반의 개발이 어려우셨다면 이제는 최신 버전의 SDK와 개발 도구를 이용하여 좀 더 편안하게 Visual Studio 2010을 통해 클라우드 기반 응용프로그램 개발을 시작해보세요. 참고로 Visual Studio 2010의 데이터베이스 탐색기는 SQL Azure 데이터베이스에 대한 탐색도 지원하므로 이전처럼 별도의 SSMSE를 필요로 하지 않습니다. 그리고 이번 버전의 SDK 역시 1.0과 1.1과 마찬 가지로 처음 설치하는 경우에는 OS와 개발 도구의 환경에 따라 패치와 핫 픽스들을 적용하셔야 합니다.

다운로드 바로가기

 

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)
닷넷 프로그래밍 커뮤니티에서 요즈음 제일 큰 이슈는 바로 .NET Framework 4와 Visual Studio 2010일 것입니다. 어느새 버전 4에 이르렀고, 정말로 많은 변화와 개선이 있었고, 그 현주소가 바로 지금 시점일 것입니다. 오늘은 .NET Framework 4에 대한, 그 중에서도 핵심 API 및 기술들에 대한 변화를 살펴보는 블로그 아티클을 올려봅니다.

진단 기능 및 성능 측정

.NET Framework 4에 들어서면서부터, CPU 사용량과 메모리 사용량을 프로세스 단위가 아닌, 응용프로그램 도메인 단위에서 측정하는 일이 가능해졌습니다. 응용프로그램 도메인은, 닷넷 프레임워크에서 사용하는 실제 실행 단위이며, 무엇보다도 중요한 것은 응용프로그램 도메인은 프로세스와 달리 닷넷 프레임워크의 관리 아래에서 통제할 수 있는 자원이라는 점입니다. (프로세스는 운영 체제의 커널에 의하여 귀속되고 관리되는 자원입니다. 따라서, 비 관리 영역에 속하는, 기본적으로는 권외 영역인 셈입니다.)

AppDomain 클래스에 추가된 새 멤버인 AppDomain.MonitoringIsEnabled 프로퍼티를 이용하여 (http://msdn.microsoft.com/ko-kr/library/system.appdomain.monitoringisenabled.aspx 참고) 현재 실행 중인 응용프로그램 도메인에 모니터링 기능이 부여되어있는지를 파악할 수 있습니다. 그리고, 이 설정을 바탕으로 CLR ETW 이벤트 (Common Language Runtime Event Tracing for Windows, http://msdn.microsoft.com/ko-kr/library/dd264810.aspx) 기능을 사용하여 오버헤드없이 성능 측정을 면밀하게 수행할 수 있게 되었습니다.

향상된 가비지 컬렉션

.NET Framework 4에 들어서면서부터 백그라운드 가비지 수집 기능이 제공되는데, 이는 이전 버전의 동시 가비지 수집을 대체하고, 좀 더 향상된 가비지 수집 처리 서비스를 제공합니다. 자세한 내용은 http://msdn.microsoft.com/ko-kr/library/ee787088.aspx 페이지의 Background Garbage Collection 섹션을 참고하시기 바랍니다.

병렬 컴퓨팅 패러다임의 지원
 
이제 .NET Framework 4에서도 병렬 컴퓨팅의 패러다임을 손쉽게 가져다 사용할 수 있게 되었습니다. 이제까지 .NET Framework에서 사용하던 비동기 프로그래밍은 Thread 클래스를 직접 사용하거나, Begin/End의 Pair로 구성된 비동기 버전의 연산, 나중에 이벤트로 결과를 통지 받는 패턴, ThreadPool 클래스의 활용과 같이 다중 Threading 작업의 세밀한 부분과 상호 작용을 고려해야 하는 패턴들이었습니다.
 
http://msdn.microsoft.com/ko-kr/library/dd460693.aspx 에서 소개하는 것 처럼 .NET Framework 4는 병렬 프로그래밍에 대한 새로운 개념들을 제공합니다. .NET Framework 4 환경에서 병렬 프로그래밍은 Task Parallel Library (TPL)에 의한 Action과 PLINQ (Parallel LINQ)에 의한 Action으로 구분됩니다.
 
Task Parallel Library의 경우, 데이터를 중심으로 비동기/병렬 연산을 수행하기 위한 시나리오, 작업 자체에 집중하여 작업의 실행 순서를 제어하고 관리하는 시나리오, 기존의 전통적인 비동기 패턴과 TPL을 통합하는 시나리오 등 다양한 시나리오를 MSDN 내에서 제공하고 있습니다. TPL을 어떻게 활용할 지를 고민하고 효율적으로 선택해야 하는 어려움이 있지만, 여러분의 응용프로그램이 Cloud Ready 응용프로그램이 될 수 있도록 도와주는 지름길로도 활용할 수 있을 것입니다.
 
그리고 PLINQ는 이미 여러 닷넷 관련 전문가분들의 블로그에서 수차례 .AsParallel() Extension Method로 소개되었던 LINQ의 Extension입니다. PLINQ에 대한 좀 더 자세한 이해는 http://msdn.microsoft.com/ko-kr/library/dd997425.aspx 에서 참고하실 수 있습니다.
 
향상된 네트워킹과 암호화
 
.NET Framework 4에서는 HttpWebRequest, HttpListener, SmtpClient, SslStream, NegotiateStream 등 여러 클래스에서 Windows 인증의 보안이 강화되었습니다. Windows 7 및 Windows Server 2008 R2에서 응용 프로그램에 대한 확장된 보호 기능을 사용할 수 있습니다. 그리고, IPv6 및 Teredo를 사용한 NAT(Network Address Translation) 통과를 지원합니다. 자세한 내용은 IPv6 및 Teredo를 사용한 NAT 통과를 참조하십시오.

HttpWebRequest 클래스에서 AddRange 메서드에 대한 새 오버로드를 통해 큰 바이트 범위 헤더(64비트 범위)를 사용할 수 있도록 지원합니다. HttpWebRequest 클래스의 새 속성을 통해 응용 프로그램에서 여러 개의 HTTP 헤더를 설정할 수 있습니다. Host 속성을 사용하여 요청 URI에 종속되지 않은 HTTP 요청에 호스트 헤더 값을 설정할 수 있습니다. 그 외에, SmtpClient 및 관련 클래스에 대한 SSL(Secure Sockets Layer) 지원 기능이 추가되었으며, MailMessage 클래스의 메일 헤더 지원 기능이 향상되었습니다.

암호화에 null 암호화를 사용할 수 있도록 지원합니다. ServicePointManager 클래스와 EncryptionPolicy 속성을 사용하여 암호화 정책을 지정할 수 있습니다. SslStream 클래스의 생성자에서 EncryptionPolicy 클래스를 매개 변수로 사용합니다.
 
ASP.NET 4
 
ASP.NET Caching을 확장할 수 있게 하는 새 API, Session State의 압축 지원 및 Application Preload 기능이 추가되어 더욱 개선된 Performance를 제공하게 되었습니다. Web Forms의 경우, 보다 통합된 ASP.NET 라우팅 지원, 향상된 웹 표준 지원, 업데이트된 브라우저 지원, 데이터 컨트롤을 위한 새 기능 및 새로운 뷰 상태 관리 기능 등이 포함됩니다. 그리고, 새로운 차트 컨트롤 등이 포함됩니다.

ASP.NET MVC 2에서는 뷰를 위한 새 도우미 메서드, 분할된 MVC 응용 프로그램에 대한 지원 및 비동기 컨트롤러 등이 포함됩니다. ASP.NET AJAX 라이브러리의 클라이언트 기반 AJAX 응용 프로그램에 대한 추가 지원 등이 포함됩니다.
그 외 변경 사항들
 
WPF 4는 이제 Silverlight 4와 동등한 컨트롤들을 제공합니다. 특히 데이터 그리드, 달력, 날짜 선택 컨트롤이 제공되고 실버라이트 응용프로그램을 거의 그대로 있는 그대로의 상태 (as-is)로 마이그레이션하는 것을 고려해 볼 수 있습니다. 자세한 내용은 http://msdn.microsoft.com/ko-kr/library/bb613588.aspx 를 참고하여 주십시오.
 
ADO.NET의 경우 ADO.NET Entity Framework에 대한 향상이 많이 있었습니다. http://msdn.microsoft.com/ko-kr/library/ex6y04yf.aspx 의 내용을 참고하여 주십시오. WCF의 경우 ASP.NET 호환 모드에서 ASP.NET Routing과 잘 통합됩니다. WCF의 새로운 기능은 http://msdn.microsoft.com/ko-kr/library/dd456789.aspx 에 잘 설명되어있으며, WF의 경우 http://msdn.microsoft.com/ko-kr/library/dd489410.aspx 의 내용을 참고하십시오.
 
지금 시작하기
 
.NET Framework 4.0의 기능을 지금 사용해보기 원하시나요? http://www.microsoft.com/express 에 방문하셔서 최신 버전의 Visual Studio 2010 Express Edition을 설치하고 지금 시작해보세요. 그리고, 2010년 6월 1일에 있을 REMIX'10 행사는 Visual Studio 2010과 함께 최신 웹 기술을 집중적으로 조명합니다. 관심있으신 개발자 여러분들의 적극적인 참여를 기대합니다. :-)
 
REMIX'10 행사 바로가기: http://www.visitmix.co.kr/remix10/index.html
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

.NET Framework 4.0과 Visual Studio 2010 RTM이 긴 테스트 과정과 수렴 과정 끝에 이번달에 성공적으로 전 세계에 런칭하였습니다. 생산성을 극적으로 업그레이드할 수 있는 다양한 기술과 API 들을 중무장하고, ASP.NET MVC2나 MEF (Managed Extensibility Framework) 등의 새로운 기술들도 다채롭게 선보였습니다.

 

그런데 한 가지 궁금증이 생깁니다. Windows Azure OS 자체는 아직도 .NET Framework 3.5 SP1을 기반으로 하는데 언제 .NET Framework 4.0으로 업데이트하는걸까요? 이에 대한 포럼 내의 답이 있어서 블로그에 소개합니다.

 

출처: http://www.mygreatwindowsazureidea.com/forums/34192-windows-azure-feature-voting/suggestions/395925-create-a-beta-environment-for-net-4-0-tests-and?ref=title

 

MIX2010에서, Windows Azure에서의 .NET Framework 4.0 지원은, RTM 버전이 공개된 이후 약 90일 이내에 업데이트된다고 합니다. 개발 과정 상의 변수 (Visual Studio용 SDK 개발, Windows Azure VM 이미지 업데이트) 등을 모두 감안한 기간으로 보입니다만, 늦어도 올해 초여름에는 .NET Framework 4.0을 기반으로 실행되는 Windows Azure 서비스를 사용할 수 있는 셈이 됩니다.

 

그렇지만, 좀 더 빠르게 .NET Framework 4.0 기반의 클라우드 응용프로그램을 개발하고 테스트하기를 희망하신다면, 배포하실 Windows Azure 환경 설정 파일에 실제로 채택할 운영 체제의 버전을 정확히 기술하여 .NET Framework 4.0 RC 버전을 채택한 VM을 기반으로 구동하도록 선택하실 수도 있습니다. 해당 버전은 Windows Azure Geust OS 1.2 중 2010년 3월 1일 버전의 이미지입니다. (http://msdn.microsoft.com/en-us/library/ff436045.aspx)

 

.NET Framework 4.0과 Windows Azure가 결합한다면, 이전보다 더 확장성이 뛰어나고 강력한 클라우드 기반 응용프로그램을 작성할 수 있는 토대가 마련될 것입니다. 여러모로 기대가 많이 되는 소식이고, 새로운 소식이 들어오는대로 정보를 공유할 수 있도록 하겠습니다. 감사합니다. :-)

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

 

2010년 3월 26일 금요일 저녁에 있었던 Cloud Application 경진대회 때 출품했던 BuzzContact 응용프로그램의 발표 자료 및 소스 코드를 공유합니다. Web Role과 Worker Role을 활용하는 예시를 포함하고 있습니다.

 

 

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

실제 Windows Azure 계정을 신청하기 이전에, Windows Azure 기반의 개발을 테스트하기 위하여 보통 Windows Azure SDK와 함께 제공되는 Development Fabric을 이용하여 주로 디버깅하실텐데요, 잘 동작하지 않아서 힘든 경우가 있습니다.

 

Windows Azure Development Fabric을 이용하여 프로그래밍할 때 경험할 수 있는 문제점 중 하나는, Development Fabric으로 디버거를 연결하거나, 응용프로그램 패키지를 Deploy할 때 실패할 가능성이 "종종" 있다는 점입니다. 이 부분에 대한 간단한 트러블슈팅 가이드를 써봅니다.

 

1. Development Fabric으로 프로그램을 배포하려고 할 때 경고 메시지가 여러번 나타난다?

 

관리자 모드로 Visual Studio를 시작하고, Development Fabric으로 디버깅을 시작하려고 할 때, 빌드 출력 창에 경고 메시지가 나타나는 경우가 있습니다. 경고 메시지의 내용은 아래와 같이 나타날 수 있습니다.

 

Windows Azure Tools: Warning: The Windows Azure development fabric and development storage are running on a 32-bit workstation. In the cloud, Windows Azure Hosted Services run in a 64-bit environment. The use of native code execution or .Net Full Trust features such as P/Invoke may require migration to 64-bit. See http://go.microsoft.com/fwlink/?LinkId=145047 for details.

 

Windows Azure 환경 위에서 실제로 운영되는 OS의 아키텍처는 32비트가 아닌 64비트 버전이기 때문에, Web Role이나 Worker Role에서 사용중인 Platform Invoke 시그니처 들이 실제 운영 환경에 배포되었을 때는 맞지 않을 수도 있으니 마이그레이션을 해야 한다는 안내 문구이며, 일반 출력 창에 나타나는 메시지이기 때문에 여러번 디버깅을 시작할 경우 여러줄에 걸쳐서 문구가 쌓여서 표시될 수 있으니 걱정하지 말고 디버깅하시면 됩니다.

 

2. Development Fabric으로 진입하는 도중에 Visual Studio가 응답 없음 - 또는 - 마우스/키보드 동작을 받아들이지 않고 경고음만을 낸다? / Development Fabric이 기동되는듯 하다가 한참 후에 Null Reference 오류가 발생한다?

 

실제 디버깅에 들어가지 못하고 Visual Studio가 먹통이 되는 경우 또한 간혹있을 수 있습니다. 이는 Development Fabric이 정상적으로 초기화되지 못하였을 경우 발생할 수 있는 문제이며, Windows Azure Development Fabric을 사용하실 때에는 아래의 내용을 숙지하셔서 Development Fabric이 정확히 초기화 작업을 처리할 수 있도록 하는 것이 좋습니다.

 

a. 한 번에 한 Windows Azure 응용프로그램에 대해서만 디버깅하실 것을 권합니다.

 

b. 디버깅이 끝나면, 작업표시줄의 트레이 아이콘 표시 영역에 나타난 Windows Azure Development Fabric 프로그램을 직접 종료하여 주십시오. 가급적, 디버깅이 끝나면 Windows Azure Simulation Service와 Storage Service는 함께 종료해야 하며, 프로그램을 직접 닫으려할 때, 기동 중인 서비스를 모두 중단시킬지 안내하는 창이 나타나면 중단하도록 선택하여 주십시오.

 

문제가 발생하였을 경우에는 다음과 같이 조치하실 수 있습니다.

 

a. 실행 중인 Visual Studio를 모두 종료하시고, Windows Azure SDK v1.1 프로그램 그룹에서 Development Fabric 아이콘을 더블 클릭하여 Standalone으로 Development Fabric을 시작합니다.

 

b. Storage 서비스의 기동 상태를 Windows Azure 아이콘을 오른쪽 버튼으로 클릭하여 확인하고, 시작되지 않았을 경우 강제로 시작을 시도합니다. 시작되지 않을 경우, SQL 서버 인스턴스가 시스템에서 실행 중인 것이 있는지 확인해 봅니다.

 

c. Show Development Storage UI 메뉴 항목을 클릭하고, 나타나는 화면에서 "Reset" 버튼을 클릭하여 스토리지 설정을 초기화하도록 예약합니다.

 

d. Windows Azure Development Fabric을 종료하며, 이 때 모든 서비스를 중단할지 묻는 메시지 박스에서 중단하도록 선택합니다.

 

e. Visual Studio를 열어서 빌드할 때, "정리" 기능을 이용하여 빌드 산출물들을 모두 제거하도록 한 후 다시 시도합니다.

 

3. Windows Azure로 응용프로그램을 개발하면서 인텔리센스 기능을 사용하려할 때 Visual Studio 2010이 갑자기 충돌을 일으키며 종료된다?

 

Visual Studio 2010 RC 패치 (KB980610)가 발표되었습니다.

위의 글에서 소개하는 KB980610 패치를 시스템에 설치하시기 바랍니다.

 

짧은 글이었지만, 도움이 되셨기를 바라며 글을 마무리해봅니다. 감사합니다. :-)

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

FIX: Visual Studio 2010 Release Candidate crashes when the IntelliSense window appears or is dismissed in Text Editor 라는 이름으로 KB980610 문서로 등록된 Visual Studio 2010 RC 패치가 나왔습니다. Visual Studio 2010 RC 버전을 통하여 프로그래밍할 때, ASPX 페이지의 인텔리센스를 사용할 때 발생할 수 있는 프로그램 충돌 현상을 수정하는 것으로 RTM 버전에서는 수정될 것으로 보입니다.

 

Windows Azure를 이용하여 샘플 프로그래밍을 할 때에도 자주 경험할 수 있는 불편 사항이므로 Windows Azure SDK를 설치하여 테스트 중이신 분들도 모두 아래의 페이지에서 제공되는 패치를 다운로드하여 설치하실 것을 권합니다. 패치 설치 작업 도중에는 관리자 권한을 필요로 합니다.

 

http://support.microsoft.com/kb/980610

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

지난번에 올린 Dynamic Programming에서, COM에 대한 Dynamic Binding을 통하여 웹 브라우저를 마치 자바스크립트로 제어하는것과 같은 편리성을 확인할 수 있었습니다. 그리고 여기에 더불어서, Dynamic Programming에 대한 재미있는 내용을 하나 더 다루어보고자 합니다.

 

System.Dynamic 네임스페이스는 닷넷 프레임워크 4.0에서 새로 소개된 네임스페이스로, Dynamic Language Runtime을 활용할 수 있도록 기본 기능들에 대한 사항들을 포함하고 있습니다. 여기서 우리가 알아두면 유용한 리소스 두 가지를 살펴보기로 하겠습니다.

 

1. DynamicObject의 재정의

 

System.Dynamic.DynamicObject 클래스는, System.Dynamic.IDynamicMetaObjectProvider 인터페이스를 구현하는 보통의 클래스입니다. 다만, 생성자가 protected로 보호되어있고, 10종류가 넘는 가상 메서드를 제공하고 있습니다.

 

DynamicObject는 Dynamic Programming에 있어서 필요한 기능들을 거의 모두 내장하고 있습니다. 가령, 컴파일 타임에서 정의되지 않은 멤버를 두고서 단항/이항 연산자를 재정의하거나, 멤버를 가져오거나, 멤버를 설정하거나, 멤버를 삭제하거나, 멤버를 호출하는 등 보편적인 객체 지향 프로그래밍 환경에서 취할 수 있는 액션들을 모두 재정의할 수 있도록 추상화하고 있습니다.

 

여기서 주목할 점은, DynamicObject의 기능을 확장하기 위하여 Expression Parser를 같이 이용한다는 점입니다. 앞 예제에서 보여드린, 마치 JavaScript처럼 코드를 자유자재로 C# 코드를 확장한 예시를 예로 들어본다면, Dynamic 컨텍스트 내에 서술한 C# 코드 조각은 Expression Parser에 의하여 처리되어 Expression 클래스의 인스턴스로 변환됩니다. 이렇게 변환된 객체는 DynamicObject에 미리 정의된 메서드들에 전달되는 것입니다.

 

다음은 Expression 객체를 사용하는 예시 코드입니다. (MSDN에서 발췌함)

 

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq.Expressions;

// The class derived from DynamicObject.
public class DynamicNumber : DynamicObject
{
    // The inner dictionary to store field names and values.
    Dictionary dictionary
        = new Dictionary();

    // Get the property value.
    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        return dictionary.TryGetValue(binder.Name, out result);
    }

    // Set the property value.
    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        dictionary[binder.Name] = value;
        return true;
    }

    // Perform the binary operation. 
    public override bool TryBinaryOperation(
        BinaryOperationBinder binder, object arg, out object result)
    {
        // The Textual property contains the textual representaion 
        // of two numbers, in addition to the name 
        // of the binary operation.
        string resultTextual =
            dictionary["Textual"].ToString() + " "
            + binder.Operation + " " +
            ((DynamicNumber)arg).dictionary["Textual"].ToString();

        int resultNumeric;

        // Checking what type of operation is being performed.
        switch (binder.Operation)
        {
            // Proccessing mathematical addition (a + b).
            case ExpressionType.Add:
                resultNumeric =
                    (int)dictionary["Numeric"] +  
                    (int)((DynamicNumber)arg).dictionary["Numeric"];
                break;

            // Processing mathematical substraction (a - b).
            case ExpressionType.Subtract:
                resultNumeric =
                    (int)dictionary["Numeric"] - 
                    (int)((DynamicNumber)arg).dictionary["Numeric"];
                break;

            // In case of any other binary operation,
            // print out the type of operation and return false,
            // which means that the language should determine 
            // what to do.
            // (Usually the language just throws an exception.)
            default:
                Console.WriteLine(
                    binder.Operation + 
                    ": This binary operation is not implemented");
                result = null;
                return false;
        }

        dynamic finalResult = new DynamicNumber();
        finalResult.Textual = resultTextual;
        finalResult.Numeric = resultNumeric;
        result = finalResult;
        return true;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Creating the first dynamic number.
        dynamic firstNumber = new DynamicNumber();

        // Creating properties and setting their values
        // for the first dynamic number.
        // The TrySetMember method is called.
        firstNumber.Textual = "One";
        firstNumber.Numeric = 1;

        // Printing out properties. The TryGetMember method is called.
        Console.WriteLine(
            firstNumber.Textual + " " + firstNumber.Numeric);

        // Creating the second dynamic number.
        dynamic secondNumber = new DynamicNumber();       
        secondNumber.Textual = "Two";
        secondNumber.Numeric = 2;
        Console.WriteLine(
            secondNumber.Textual + " " + secondNumber.Numeric);
       

        dynamic resultNumber = new DynamicNumber();

        // Adding two numbers. The TryBinaryOperation is called.
        resultNumber = firstNumber + secondNumber;

        Console.WriteLine(
            resultNumber.Textual + " " + resultNumber.Numeric);

        // Subtracting two numbers. TryBinaryOperation is called.
        resultNumber = firstNumber - secondNumber;

        Console.WriteLine(
            resultNumber.Textual + " " + resultNumber.Numeric);

        // The following statement produces a run-time exception
        // because the multiplication operation is not implemented.
        // resultNumber = firstNumber * secondNumber;
    }
}

// This code example produces the following output:

// One 1
// Two 2
// One Add Two 3
// One Subtract Two -1

 

Expression 객체를 받아서, 이항 연산을 수행하는 부분을 살펴보면, 언어의 종류에 관계없이 Expression Parser를 이용하여 처리된 구문 분석 결과를 사용한다는 것을 알 수 있습니다. 즉, C#이나 Visual Basic .NET 같은 기본 런타임 언어 뿐만 아니라, IronPython과 같은 언어에도 대응이 가능함을 뜻합니다. 이러한 기능을 활용하여, 메서드의 추가 없이 언어의 특성 만으로 원하는 기능까지 이끌어내는 것이 좀 더 손쉽습니다. 예를 들어, 별도의 메서드 호출 없이 문자열 간 이항 연산 중 더하기 연산에서 HTML에 대응할 수 있도록 <BR /> 태그를 자동으로 덧붙이는 기능을 생각해 볼 수 있을 것입니다.

 

2. Anonymous Type과 ExpandoObject

 

C# 3.0에서는 익명 형식이 도입되었습니다. 이것은 전적으로 LINQ와 같이 동적으로 데이터 형식을 확장해야 하는 시나리오에 최적화된 기술로, LINQ를 위한 새로운 클래스를 작성하는 수고를 덜어주게 됩니다. (Where 절이나 Select절에서 여러 조건을 지정하는 시나리오를 생각하시면 쉽습니다.)

 

그러나 지금 소개하는 ExpandoObject는 어떤 시점에서 임시로 필요한 형식을 개설하는 일과는 별도로, 전형적인 스크립트 언어의 동적 형식을 구현한 것으로, 익명 형식이 컴파일러에 의하여 동적으로 추가되지 않고, 런타임에서 키와 값의 쌍으로 이루어진 Dictionary Type의 객체를 만드는 것이 조금 다릅니다. 이러한 기능 자체는 이미 C# 초기 버전부터 제공되어오던 Hashtable이나 C# 2.0의 Generic 버전의 Dictionary<TKey, TValue> 형식을 이용하는 것과 개념상 유사하지만, 문법적인 관점에서 좀 더 업그레이드 된 형태로 이해할 수 있습니다.

 

아래는 ExpandoObject를 Dynamic Context 아래에서 활용하는 예시입니다.

class Program
{
    static void Main(string[] args)
    {
        dynamic employee, manager;

        employee = new ExpandoObject();
        employee.Name = "John Smith";
        employee.Age = 33;

        manager = new ExpandoObject();
        manager.Name = "Allison Brown";
        manager.Age = 42;
        manager.TeamSize = 10;

        WritePerson(manager);
        WritePerson(employee);
    }
    private static void WritePerson(dynamic person)
    {
        Console.WriteLine("{0} is {1} years old.",
                          person.Name, person.Age);
        // The following statement causes an exception
        // if you pass the employee object.
        // Console.WriteLine("Manages {0} people", person.TeamSize);
    }
}
// This code example produces the following output:
// John Smith is 33 years old.
// Allison Brown is 42 years old.

 

그리고 아래의 코드는 Dictionary의 경우와 마찬가지로, ExpandoObject의 모든 멤버들을 Reflection 없이 나열하는 것입니다. (내부적으로 Dictionary와 같은 개체를 사용하여 멤버들을 관리하고 있으므로 Reflection을 이용하지 않는것으로도 볼 수 있습니다.)

dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;

foreach (var property in (IDictionary)employee)
{
    Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33

 

ExpandoObject는 문법적으로 Dictionary 컬렉션을 확장한 것으로 이해할 수 있기 때문에, 확정적이지 않은, 변동 가능성이 있는 다수의 매개 변수를 복잡하지 않게, 문법적으로 융합된 형태로 코드를 작성하기 수월하게 합니다. Dictionary 컬렉션 개체를 생성하고 넘기는 동작을 미화한 것으로 볼 수 있을 것입니다.

 

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

Visual Studio 2010 베타 2가 이 글을 쓰는 현 시점에 Express Edition과 함께 새롭게 공개되었습니다. .NET Framework 4.0과 더불어서 C# 4.0, Visual Basic .NET 10.0 등 언어들의 기능도 새롭게 향상되었으며, 특히 이목을 끄는 것은 Dynamic Language Runtime과 연동되는 Dynamic Programming에 관한 것입니다.

 

Dynamic Programming에 대해서, 철수네 소프트웨어 세상 블로그 (http://blogs.msdn.com/bkchung/)에 소개된 내용을 오래 전에 처음 포스팅을 했었지만 최근까지도 dynamic 키워드의 실용적인 사례를 찾지 못하고 있었습니다만, 최근 dynamic 키워드의 새로운 활용 가능성을 새롭게 발견하였습니다. 여러 시나리오가 있을 수 있겠지만 제가 오늘 이 포스트를 통해서 조명해보고자 하는 것은 Windows Forms가 제공하는 Web Browser와의 연동에 관한 것입니다.

 

Windows Forms가 버전 2.0에 들어서면서부터 매우 실용적인 컴포넌트를 새롭게 추가하였는데 바로 웹 브라우저 컨트롤이 그것이었습니다. 웹 브라우저 컨트롤은 단순히 브라우저로서도 활용할 수 있지만 잘 활용한다면 사용자 인터페이스를 웹 기반으로 업그레이드하는 것 또한 가능합니다.

 

하지만 COM Interop 프로그래밍에 기댈 수 밖에 없는 부분은 여전히 많았고, 당시의 C# 언어 사양만으로 COM Interop을 다루는데에는 비효율적이고 생산성이 떨어지는 부분이 많았습니다. 그런 이유로, 예전의 브라우저 컨트롤보다는 "조금 뛰어난" 수준으로 인지되는데에 그쳤습니다. 하지만 이번에 새로 소개되는 Dynamic Programming과 결합하면 매우 매력적인 프레임워크로 다시 거듭나게 됩니다.

 

Dynamic Programming을 시험해볼 좋은 자바스크립트 예제를 찾던 중, http://www.javascriptfreecode.com/34.htm 의 소스 코드를 발췌하여 Dynamic Programming 버전으로 만들어보았습니다.

 

본디 이 스크립트가 하는 일은 Internet Explorer가 고유하게 제공하는 웨이브 필터를 활용해서 텍스트를 화려하게 보일 수 있도록 치장하는 것입니다. 그러나 이 기능을, 여러 브라우저가 보는 페이지로서가 아닌, 온전히 Windows Forms 응용프로그램만을 위한 고유한 기능으로 바꾸어보도록 하겠습니다.

 

  1. 폼에 웹 브라우저 컨트롤을 새로 추가합니다.
  2. 웹 브라우저 컨트롤이 처음 보일 페이지를 about:blank 로 설정합니다. 빈 문서를 준비시키도록 하는데에 도움이 됩니다.
  3. 기본 이벤트인 DocumentCompleted 이벤트 핸들러를 새로 추가합니다.
  4. 아래의 코드를 작성합니다.

private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    dynamic document = this.webBrowser.Document.DomDocument;
    dynamic window = this.webBrowser.Document.Window.DomWindow;

    document.write(String.Format(@"
<!-- Original Source: http://www.javascriptfreecode.com/34.htm -->
<div id=""Zittertext"" style=""font-weight: bold; font-size: 25pt; filter: Wave(freq=5, light=0, phase=8, strength=1); width: 100%; color: orange;"">
<div style=""background-color: #FFFF00; text-align: center; color: black; display: inline;"">
{0}
</div>
</div>
", window.prompt("Please type a message to display: ", "Hello World!")));

    Action DynWave = () =>
    {
        dynamic filter = document.getElementById("Zittertext").filters[0];
        if (filter.freq > 130)
            filter.freq = 15;
        filter.freq++;
        if (filter.phase > 50)
            filter.phase = 1;
        filter.phase++;
        if (filter.strength > 1)
            filter.strength = .1;
        filter.strength++;
    };

    Timer timer = new Timer();
    timer.Tick += (a, b) => DynWave();
    timer.Interval = 50;
    timer.Enabled = true;
}

 

위의 코드에서 우리가 관심있게 봐두어야 할 부분은 dynamic으로 선언한 변수 뒤에 나타나는 표현식들입니다. 컴파일러 기반의 언어들은 늘 그렇듯 문법의 정확성을 언제나 따지게 됩니다. C#도 분명히 그런 언어였습니다. 하지만 Dynamic Programming을 통하여 위와 같이 컴파일 시점에는 존재하지 않는 내용을 런타임 때에 유추해낼 수 있게 되었습니다.

 

여기서 의문점이 드는 것이 있는데, 그렇다면 이를 유추해내기 위해서 어떤 식으로 구현을 제공하는가에 대한 부분입니다. 이 부분에 대한 답은 바로 .NET Framework가 런타임 과정에서 정확한 객체 정보를 확인하기 위해서 사용하는 ObjectBinder에 있습니다. regasm 유틸리티로 등록해두었던 COM Interop Assembly나 Primary Interop Assembly에 대한 내용을 런타임 차원에서 관리하고, 이를 자동으로 연결하고 있는 것입니다. 직접 프로젝트에서 참조를 하지 않았다고 할지라도 그러합니다.

 

그리고 이러한 기능 위에 DLR과 더불어서 이미 LINQ에서 소개된 적이 있는 Expression Tree 해석 엔진에 의하여 C# 기준으로 작성된 코드를 Object Binder가 가지고 있는 정보와 일치시켜 정확한 기능을 하는 실제 코드를 컴파일 과정에서 작성하게 되는 것입니다. 이것은 형식 정보를 읽어서 매번 같은 컬렉션을 여러번 반복하면서 조회하는 Reflection 기반의 프로그래밍보다 훨씬 빠르게 동작하고, 훨씬 정확도가 높습니다.

 

위의 코드를 실행한 결과는 아래와 같습니다. 중간에 어떤 메시지를 표시할 것인지를 묻는 브라우저의 프롬프트 창에 원하는 메시지를 넣어보는 것도 괜찮을 것입니다.

 

 

Dynamic Programming에 대한 자세한 내용은 http://msdn.microsoft.com/en-us/library/dd264736(VS.100).aspx 의 내용을 참고하시면 도움이 될 것입니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)