분류 전체보기 (328)
.NET (111)
OOP (10)
Event (0)
웹서비스 (1)
ASP.NET (40)
C# (37)
JavaScript (10)
ADO.net (1)
XML.net (1)
Exchang server 2010 (3)
WPF (0)
HTML/CSS (6)
S/W tip (35)
etc (63)
DB (34)
HOT item~! (48)
Disign pettens (4)
UX (6)
나의 S/W (2)
개발관련 이슈 (16)
Diary (1)
웹플러스 (1)
calendar
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
tags
archive
link
ColorSwitch 00 01 02
▣  .NET/C# - 해당되는 글 37건

출처 : http://www.hoons.net/Board/itdisc/Content/34650 

 

애자일은 많은 경험을 할수록 더 많은 고민을 만드는 장본인인 것은 확실 한 것 같습니다.

하지만 대부분의 IT 산업이 그러하듯이 우리나라에만 도입되면 변질, 변형 되는 경우가 많습니다.

그 중에서 애자일도 예외는 아닙니다.

가끔 생각하는 것이 누구를 위한 애자일인가란 고민을 합니다.

개인적인 경험으로는 애자일을 팀원이 느끼지 못하도록 유도하는 것이 솔직하게 정신 건강상 이롭더라구요.

여러분은 어떤 생각으로 애자일을 접근하는지... 또는 접근당하는지...

궁금합니다.^^





애자일에 대한 고찰에 앞서 먼저 '정말 TDD  필요한가?'  대해 이야기 부터 시작해봅니다.


애자일에 대한 고찰

애자일 프로그래밍이 도마에 오르면서 단연 단위 테스트(Unit Test)와 TDD(Test Driven Development) 를 빼놓을 수 없습니다. 단위 테스트와 TDD는 상호 공생 관계에 놓이면서, 둘 중 어느하나 포기하기 쉽지 않습니다. 왜냐하면 TDD에 대한 이상론자들은 TDD의 중요성을 매우 높이 강조하고 있기 때문입니다.

필자는 이에 대해 정말 개발에 TDD가 얼마나 좋고 효과가 좋은지 사실 산술적으로 검증할 수는 없다고 생각합니다. 좋은 것이 있는 많큼 잃는 것도 있을테니까요.


TDD 를 해야한다는 관점

일반적으로 코드를 작성한 후에 그 기능을 테스트하는 코드를 작성하는 것을 단위 테스트라고 합니다. 단위 테스트를 작성함으로써 결함없는 소프트웨어를 만들기 위한 지속적인 통합(CI-Continuous Integration) 라는 관점에서 상당히 효과적인 방법입니다.

여기에서 TDD 는 단위 테스트를 작성하는 단계의 순서를 기존의 Last 에서 First 로 바꾸면서, 단위 테스트 코드를 먼저 작성하도록 하는 방법입니다. 처음 오류가 날 수 밖에 없는 코드를 테스트하면서 Red, Green, Refactor 단계로 옮겨가도록 하는 기법입니다.

사실 이런 저런 TDD 의 효과중에 단연, 코드가 매우 견고해진다는 큰 장점이 있습니다.    

 

처음부터 기능을 구현하는 코드를 작성하게 된다면, 클래스와 메서드를 잘 분리한다고 하더라도 한 클래스나 메서드는 생각지도 않게 기능의 크기가 커질 수 밖에 없습니다. 왜냐하면 코드 작성자는 코드를 만드는 목적이 기능이 정상적으로 작동해야 한다는 전제하에 코드를 만들기 때문에 오류 없는 코드가 목적이기 때문입니다.

또 한가지 TDD를 하지 않는다면 코드의 리팩토링을 코드가 완료된 이후에만 가능하다는 것입니다. 지속적으로 이런 문제는 소프트웨어의 디자인이 바뀌거나 오류가 발생하지 않을 경우 굳이 리팩토링을 하지 않게 되죠.

결국 어떤 이유에서든지 좋은 코드를 만들기 위해서는 TDD가 매우 좋은 기법이 될 수 있습니다. 쉽게Database 를 예로 들자면, 초기에 테이블을 정규화할 것인지, 나중에 문제가 생길 경우 정규화를 할 것인지의 고민과 유사하기도 합니다. 하지만 절대 변하지 않는 진리는, 처음부터 갈귀갈귀 정규화를 한 것을 합치는 것은 쉬워도, 통짜를 분리하는 것은 사실 엄청난 리스크가 됩니다.


TDD 를 하지 말아야한다는 관점

개인적으로 필자는 이 부류에 속하기도 합니다. 누구든 TDD를 알게 되면 그것이 가지는 이상적인 효과를 이해할 수 있습니다. 하지만 살짝 TDD에 발가락을 담구어보면 금방 TDD에 대해 의심을 하게 됩니다. 바로TDD를 해보면 너무 어렵다는 것입니다.

첫번째로 RedGreen, 그리고 최종적으로 Refactor 단계로 가는 과정이 오래 걸리고 어렵습니다. TDD코드를 만들기 시작하는 순간부터 리팩토링의 시작이며, 길지 않은 코드조차 굉장히 버겁다는 것을 알 수 있죠. 정말 지루하고도 기계적인 과정입니다.

두번째는 이미 언급했다시피 지루하고도 기계적인 과정입니다. 즉 TDD기법으로 생상되는 코드는 기존에 코드를 만들고 테스트하는 예상 시간이 +a 가 됩니다. 코드의 양에 비례하여, 'stub(코드의 양) * alpha(가중치) = TDD 수행시간' 이라는 대략적인 예측 소요 시간이 걸릴 것입니다.

 

TDD의 시작은 곧 리팩토링의 연속입니다. 아무리 개발 도구가 좋아진다고 하더라도 사람이 하던 리팩토링을 대신해줄 수는 없을 것입니다. 즉, TDD기법을 도입하기 위해서 기존 방식의 산술적인 계산법으로 더 이상 기간과 공수를 예측할 수 없습니다. 분명 시간과 비용이 터무니없이 증가할 것입니다.

아마도 우리나라에서는 TDD를 조직내에서 개발 방법으로 채택하는 곳은 없다고 봅니다. 우리나라에서는 소프트웨어의 생산 기간을 어떻게 줄일까에 집중하고 있기 때문에, TDD는 팀과 조직의 goal 에 방해 요소만 뿐입니다효용성 측면에서 TDD 본다면 그저  좋은 개살구로 보이기 쉽기 때문입니다.


애자일을 명목으로 스스로 족쇄를 차고있는 우리 조직

애자일이라는 이름과 이상적인 가이드를 이행하려는 조직에서 특히 불화음이 많을 것입니다. 그리고 그들은 애자일을 해 본 결과 애자일은 왜 실패하냐는 물음을 던집니다. 사실 애자일이 가지는 그 사상은 굉장히 높이 살만 합니다. 기존의 폐쇄적인 조직을 개방하려는 의지를 보인다는 것으로 시작하여 팀간의 커뮤니케이션을 향상시키도록 합니다.

그런데 애자일을 도입하려는 사람들은 큰 함정에 빠집니다. 팀을 위한다는 명목으로 너무 많은 것을 팀에게 강요합니다. 자신이 바라보기엔 좋은 기법들이 많고 팀에게 전파하려고 노력하겠지만, 팀은 이미 기존에도 잘 되고 있는 부분을 왜 뜯어고치려는지 이해할 수 없기 때문이죠. 팀에게 변화라는 명목으로 팀원들의 공감을 얻지 못한채로 강요를 시작하게 됩니다.

사실 애자일한 팀과 애자일한 프로그래밍을 위해 애자일은 아무것고 강요하지 않습니다. 그런데 누군가의 손에 애자일이 쥐어지면 은근히 강요로 변질되는 경우가 대부분입니다.

 

애자일 중에, 특히 XP(eXtreme Programming) 는 우리나라 실정이 전혀 반영되지 않았습니다. XP 의 여러가지 기법 중에 특히 코드 리뷰 와 짝 프로그래밍이 대표적이죠. 짝 프로그래밍은 짝이 되어 서로의 생각과 노하우를 전수해 주는 기법이지만, 필자로써는 '글쎄…'

필자는 오히려 짝 프로그래밍을 함으로써 개인 업무 시간을 너무 할애당한다는 생각이 듭니다. 필자가 메신저의 채팅보다 이메일을 좋아하는 이유도 여기에 있습니다. 업무 진행에 탄력을 받다가도 채팅으로 내 생각의 컨텍스트가 강제로 전환됩니다. 생각이 정리되지 않은 상대편이 타자를 치고있는 것을 멍하니 바라만 봅니다. 기술적인 것을 물어볼땐 답을 알려줘도 채팅이라는 특성상 한번에 한줄의 글로 모든 것을 표현하기가 힘듭니다. 만약 이메일이었다면 보낸 사람도 생각을 정리해서 보냈을테고, 또한 내가 보고싶을 때 보고, 명쾌한 MSDN 링크와 곁들여 오히려 짧은 시간에 높은 성과를 낼 수 있을텐데요...

결국 짝 프로그래밍은 그것을 성취한 후의 성과가 소비된 리소스에 비해 턱없이 낮으며, 짝 프로그래밍의 특성상 지속성을 유지하기에 한계가 있습니다.

 

또, 코드 리뷰를 진행하기 위해 다양한 기법들과 절차를 선보입니다. Self Review, Pair Review, TeamReview 등 전혀 현실을 고려하지 않고 단지 그 기법들에 대해서만 매달리는 사람들이 많습니다. 특히 코드 리뷰는 도구를 이용한 자동화를 하지 않을 경우 있으나 마나한 기법입니다. 장기적으로 코드 리뷰는 형식적일 수 밖에 없습니다.

더 중요한 것은 코드 리뷰 기법이 아니라, 프로세스적으로 이것을 통제하여 코드 리뷰 책임자를 두는 것이 효과적일 수 있습니다. 보안이나 성능 등에 관련하여 코드 리뷰의 책임을 위임하고, 보안이나 성능 문제 발생시에 책임을 물을 수 있도록 체계화된 프로세스 말입니다.

사실 이런 면에서 기존의 애자일인 XP(eXtreme Programming) 이나 스크럼(Scrum) 보다 MSF(Microsoft Solution Framework)  기존 애자일 방법론을 현실적이고 수행가능하도록 체계화시킨 프로세스이기도 합니다.

   

입장이 서로 다른 애자일

대부분 현장에서 개발하시는 분들은 내 옆의 동료나 우리 팀보다 자기 개인이 더 중요할 것입니다. 개인 업무 성과가 팀과 조직이 나를 판단하는 기준이 대부분의 경우이기 때문입니다. 또 어떤 경우는 개발자의 특성상 발언권이 없는 경우도 있을 것입니다.

이에 반해 팀의 관리자의 평가는 자신이 관리하는 팀 전체의 성과가 조직이 관리자를 판단할 것입니다. 팀 프로젝트나 팀의 업무 성과가 낮다는 것은 관리자의 능력과 비례하기도 합니다.

 

결과적으로 애자일이라는 공통 분모로 애자일의 목표를 이루고자하는 시각이 전혀 다르다는 것이죠. 서투른 애자일은 팀원의 불만만 증가할 뿐, 팀원과 공감대를 이루기 힘듭니다. 관리자의 입장에서는 팀원간의 커뮤니케이션을 높이고 팀원 스스로 변화하길 기대하고 이것이 소리없는 강요가 될 수 있습니다.

   

애자일을 성공시키기 위해

앞서 이야기한 바와 같이 애자일이라는 목표와 사상은 굉장히 좋습니다. 그것이 팀과 조직뿐만 아니라, 개인, 가족, 단체, 사회, 국가적으로 비유해도 좋은 모델이 될 것입니다. 하지만 애자일, 특히 XP 가 이루는 그 구성 요소들은 조금은 허무맹랑한 것들이 많습니다. TDD나 짝 프로그래밍, 코드 리뷰 등 현실성이 부족한 것들을 이행하기를 권장합니다. 적어도 우리나라에서는 그것을 이행하기 위한 주변 여건이 좋지만은 않지요.

 

예전 트로이 목마라는 전쟁 이야기에서 나오듯이, 적진에게 해를 가하기 위해 트로이 목마를 적진에게 가져다 놓았습니다. 적진은 트로이 목마를 보며 마치 신이 주신 선물로 생각하겠지만 정작 트로이 목마는 적군에게 해가 되는 무시무시함을 가졌습니다.

과학에서 모든 물체는 현재 상태를 유지하려는 힘, 관성을 가지고 있듯이 우리의 팀과 조직도 마찬가지 입니다. 애자일도 마찬가지로, 그것이 좋아보인다고 자신의 팀과 조직에 구역구역 쑤셔넣다보면 상태를 유지하려는 관성을 가진 구성원과 바로 맞닿을 수 있습니다. (물론 애자일이 해를 가한다는 의미는 아닙니다)

   

 

애자일이 추구하는 여러 구성 요소는 짧은 반복으로 결과물의 품질을 높이고 결함을 줄이고자 합니다애자일의 대부분의 구성 요소는 짧은 반복으로 인한 높은 위험성을 줄이기 위한 보조적인 수단이라는 것입니다.예를 들면, 스크럼(Scrum) 을 도입한다고 해서 대시보드와 붙이는 메모지를 준비하고, 매일 매일 스크림 미팅을 할 필요는 없습니다. 스크럼 미팅이라는 형식에 갇히는 순간부터 자멸의 길이라는것을 뒤늦게 깨닳게 될 것입니다. 즉 스크럼 미팅은 매일할 필요도 없으며 어떤 다른 모습으로 바뀔 수 있고, 동료와 담배를 피거나 커피를 먹으면서 알게 모르게 나타날 수도 있습니다. 어떤 경우는 상대편 알게 모르게 하는것이 자연스러운 참여에 도움이 되는 경우도 있지요.

결론적으로 팀과 조직, 구성원 개인의 차이를 인정하고팀과 조직의 문화를 최대한 유지하는 것이 성공하는 애자일이 되는 것입니다. 필자 또한 이것을 깨닿기까지 많은 시행 착오를 겪으며 애자일로 인한 물음표에 종지부를 찍을 수 있었습니다. 즉, 애자일로 스스로에게 족쇄를 차지 마십시오. 족쇄를 끊은 후에야 진정한 애자일이 당신의 곁에 있음을 느낄 수 있을 것입니다.


서비스 프로젝트 만들기

 새 프로젝트 생성 -> windows -> windows 서비스

Service1.cs 파일이 생성되며 해당 클래스 파일에서 서비스 시작 함수 및 종료 함수가 오버라이드 되어 있고

ServiceBase클래스에 다른 함수들도 추가적으로 구현(virtual void)되어 있으므로 Override를 이용하여 상속받아 재 사용하면 된다.

서비스 설정하기

Service1.cs[디자이너] -> 설치 관리자 추가 -> ProjectInstaller.cs 생성 됨 

서비스 등록하기(.bat로 만들어서 관리하면 편하다)

서비스 등록

@SET NetFrameworkDir=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
@SET PATH=%path%;%NetFrameworkDir%

installutil Webplus.HyundaiMipo.MDS.Agent.HEMDClaimSyncService.exe

PAUSE

서비스 삭제

@SET NetFrameworkDir=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
@SET PATH=%path%;%NetFrameworkDir%

installutil /u Webplus.HyundaiMipo.MDS.Agent.HEMDClaimSyncService.exe

PAUSE

 

등록된 서비스 확인하기

제어판 -> 관리도구 -> 서비스 

 

 


▣  foreach문에서 delete하기 - .NET/C# - 2012. 11. 2. 09:50

보통 collection을 foreach문을 사용하여 지울때 collection값이 바뀌면서 루프가 꼬이게 되어 에러를 뱉어내게 되어있는데

그래서 for문을 사용하거나 해야 하는데

간단하게 foreach문을 사용하여 해결하는 방법이 있다.


바로 select() 함수 이용하기!!!!

  

foreach (Hashtable ht in htList)

{

//이 부분을 dt.Rows가 아닌 dt.Select()를 이용하여 리턴 받는다. select는 다이나믹하게 row를 리턴해주기 때문에 아무 문제 없다.

      foreach (DataRow dr in dt.Select())

      {

            IDictionaryEnumerator myEnumerator = ht.GetEnumerator();

 

            while (myEnumerator.MoveNext())

                  {

                        if (dr[myEnumerator.Key.ToString()].ToString().Equals(myEnumerator.Value))

                        {

                              dr.Delete();

                        }

                  }

      }

}




코딩을 하다보면 overloading를 많이 사용하게 되는데

그러다보면 어쩔 수 없이 파라미터로 인하여 코드가 길어지게 되는 경우가 있는데 그럴때 사용하면 아주 유용한 기술인 것 같습니다.

메서드의 파라미터에 기본값을 주어 값을 할당하지 않고 호출하는 경우 해당 기본값을 사용하는 것을 말합니다.


static void Main(string[] args)

            {

                  Program pm = new Program();

 

                  //optional parameters 호출

                  pm.OptionalTest("min"); //str1의 값을 넘겨주지 않기 때문에 기본값은 1이다.

                  pm.OptionalTest("min", "2"); //str1의 값은 2이다.

 

                  pm.NamedTest("min", str2: "0"); //str="min", str1="1", str2="0"

                  pm.NamedTest(str : "min", str1 : "0");

            }

 

            //optional parameters(default parameters)

            protected void OptionalTest(string str, string str1 = "1")

            {

                  //로직구현

            }

 

            //named parameters

            //디폴트 파라미터가 여러개일때

            protected void NamedTest(string str, string str1 = "1", string str2 = "2")

            {

                  //로직구현

            }





▣  c# 시간 계산하기 - .NET/C# - 2012. 2. 8. 18:15


출처 :  http://blog.naver.com/dragon262?Redirect=Log&logNo=110113311659

 

C# 으로 시간계산

C#에서 시간에 대한 데이타형은 2종류입니다.

DateTime과 TimeSpan

DateTime은 시각으로 2000년2월1일 이렇게 시각을 정할때 사용하고

TimeSpan은 시간으로 100일을 더하고 싶으면 TimeSpan.FromDays(100)이렇게 하면

100일을 tick으로 환산하여 계산합니다.100일을 초로 알고싶으면 초나 분으로도 알수있습니다.

 

응용하면 D-day계산등이 가능합니다.

 

시각(DateTime) - 시각 = 시간(TimeSpan)

시각 - 시간 = 시각

 

시각 + 시간 = 시각

 

소스코드

using System; namespace NET402 {

class Ex019_DateTime {

public static void Main(string[] args) { //내가 태어난지 몇일?? //현재시각 - 태어난시각 DateTime birthday = new DateTime(1985,11,26,12,20,30);//내생일 //시각(DateTime) - 시각 = 시간(TimeSpan) TimeSpan result = DateTime.Now - birthday; Console.WriteLine(result); Console.WriteLine(result.TotalDays); Console.WriteLine("{0:N0}일", result.TotalDays); Console.WriteLine("{0:N0}시간", result.TotalHours); Console.WriteLine("{0:N0}시간", result.Hours); //올해 크리스마스는 몇일 남았는지? DateTime christmas = DateTime.Parse("2011년12월25일0시0분0초"); TimeSpan result2 = christmas - DateTime.Now; Console.WriteLine("올해 크리스마스는 {0:N0}일", result2.TotalDays); //시각 + 시간 = 시각 //예) 지금으로 부터 100일 뒤는 몇일입니까? // 생일 -> 30일? 50일? 100일? 돌? DateTime baby = new DateTime(2011, 1, 20); //시각 = baby + 100일(TimeSpan.FromDays(100);) DateTime result3 = baby + TimeSpan.FromDays(100); Console.WriteLine(result3); DateTime result4 = DateTime.Now + TimeSpan.FromMinutes(45); Console.WriteLine(result4); //시각 + 시간 = 시각 //시각 - 시간 = 시각 //오늘부터 백일후? //Now + TimeSpan.FromDays(100) DateTime result5 = DateTime.Now.AddDays(100); //Console.WriteLine(DateTime.Now.AddDays(100)); Console.WriteLine(result5); //오늘부터 백일전 DateTime result6 = DateTime.Now.AddDays(-100); Console.WriteLine(result6); }

}

}

------------------------------------------------------------------

 

결과

 

---------------------------------------------------------------------------

예제2 소스코드

using System; namespace NET402 {

class Ex018_DateTime {

public static void Main(string[] args) { //날짜 시간 데이터 // - DateTime 구조체 //날짜시간 생성 // 1. 현재 시간 // 2. 특정 사간 //현재 시간 // - 시스템의 현재 시간을 가지고 구조체를 만들어서 돌려줌(Now) DateTime dt1 = DateTime.Now; Console.WriteLine(dt1);//4:30:00 //시간이 10분 흘렀음...(가정) dt1 = DateTime.Now;//4:40:00 Console.WriteLine(dt1);//4:40:00?OX Console.WriteLine(dt1.Year); Console.WriteLine(dt1.Month); Console.WriteLine(dt1.Day); Console.WriteLine(dt1.Date); Console.WriteLine(dt1.Hour); Console.WriteLine(dt1.Minute); Console.WriteLine(dt1.Second); Console.WriteLine(dt1.Millisecond); Console.WriteLine(dt1.DayOfYear); Console.WriteLine(dt1.DayOfWeek); Console.WriteLine(dt1.Ticks); //현재시간 "5시 50분 18초" Console.WriteLine("{0}시 {1}분 {2}초", dt1.Hour, dt1.Minute, dt1.Second); //특정 시간 DateTime dt2 = new DateTime(2011, 7, 13, 16, 58, 30); DateTime dt3 = new DateTime(1980, 5, 20); // "문자열" -> 자료형 DateTime dt4 = DateTime.Parse("2000-5-20"); Console.WriteLine(dt4); }

}

}

------------------------------------------------------------------------------

결과

 


▣  인자값과 매개변수의 차이점 - .NET/C# - 2012. 1. 12. 11:17
인자

인자 함수를 호출하는 입장에서 넘겨주는 값

매개변수

인자를 받은 값

EX)
getTest(num); - 이 메서드를 호출했다면 "num"이 인자가 된다.
getTest(int num)  - 메서드 구현부분에서의 "num"이 매개변수가 된다.
top
:

▣  Asynchronous Delegate - .NET/C# - 2011. 8. 5. 13:13
top
:

▣  encoding - .NET/C# - 2011. 7. 26. 16:44

출처 : http://msdn.microsoft.com/ko-kr/library/system.text.encoding.aspx


코드 페이지

이름

표시 이름

37

IBM037

IBM EBCDIC(미국-캐나다)

437

IBM437

OEM 미국

500

IBM500

IBM EBCDIC(국제)

708

ASMO-708

아랍어(ASMO 708)

720

DOS-720

아랍어(DOS)

737

ibm737

그리스어(DOS)

775

ibm775

발트어(DOS)

850

ibm850

서유럽어(DOS)

852

ibm852

중앙 유럽어(DOS)

855

IBM855

OEM 키릴 자모

857

ibm857

터키어(DOS)

858

IBM00858

OEM 다국 라틴 문자 I

860

IBM860

포르투갈어(DOS)

861

ibm861

아이슬란드어(DOS)

862

DOS-862

히브리어(DOS)

863

IBM863

프랑스어(캐나다)(DOS)

864

IBM864

아랍어(864)

865

IBM865

북유럽어(DOS)

866

cp866

키릴 자모(DOS)

869

ibm869

현대 그리스어(DOS)

870

IBM870

IBM EBCDIC(다국 라틴 문자-2)

874

windows-874

태국어(Windows)

875

cp875

IBM EBCDIC(현대 그리스어)

932

shift_jis

일본어(Shift-JIS)

936

gb2312

중국어 간체(GB2312)

*

949

ks_c_5601-1987

한국어

950

big5

중국어 번체(Big5)

1026

IBM1026

IBM EBCDIC(터키어 라틴 문자-5)

1047

IBM01047

IBM 라틴어-1

1140

IBM01140

IBM EBCDIC(미국-캐나다-유럽)

1141

IBM01141

IBM EBCDIC(독일-유럽)

1142

IBM01142

IBM EBCDIC(덴마크-노르웨이-유럽)

1143

IBM01143

IBM EBCDIC(핀란드-스웨덴-유럽)

1144

IBM01144

IBM EBCDIC(이탈리아-유럽)

1145

IBM01145

IBM EBCDIC(스페인-유럽)

1146

IBM01146

IBM EBCDIC(영국-유럽)

1147

IBM01147

IBM EBCDIC(프랑스-유럽)

1148

IBM01148

IBM EBCDIC(국제-유럽)

1149

IBM01149

IBM EBCDIC(아이슬란드어-유럽)

1200

utf-16

Unicode

*

1201

unicodeFFFE

유니코드(Big endian)

*

1250

windows-1250

중앙 유럽어(Windows)

1251

windows-1251

키릴 자모(Windows)

1252

Windows -1252

서유럽어(Windows)

*

1253

windows-1253

그리스어(Windows)

1254

windows-1254

터키어(Windows)

1255

windows-1255

히브리어(Windows)

1256

windows-1256

아랍어(Windows)

1257

windows-1257

발트어(Windows)

1258

windows-1258

베트남어(Windows)

1361

조합

한국어(조합)

10000

macintosh

서유럽어(Mac)

10001

x-mac-japanese

일본어(Mac)

10002

x-mac-chinesetrad

중국어 번체(Mac)

10003

x-mac-korean

한국어(Mac)

*

10004

x-mac-arabic

아랍어(Mac)

10005

x-mac-hebrew

히브리어(Mac)

10006

x-mac-greek

그리스어(Mac)

10007

x-mac-cyrillic

키릴 자모(Mac)

10008

x-mac-chinesesimp

중국어 간체(Mac)

*

10010

x-mac-romanian

루마니아어(Mac)

10017

x-mac-ukrainian

우크라이나어(Mac)

10021

x-mac-thai

태국어(Mac)

10029

x-mac-ce

중앙 유럽어(Mac)

10079

x-mac-icelandic

아이슬란드어(Mac)

10081

x-mac-turkish

터키어(Mac)

10082

x-mac-croatian

크로아티아어(Mac)

12000

utf-32

유니코드(UTF-32)

*

12001

utf-32BE

유니코드(UTF-32 Big endian)

*

20000

x-Chinese-CNS

중국어 번체(CNS)

20001

x-cp20001

TCA 대만

20002

x-Chinese-Eten

중국어 번체(Eten)

20003

x-cp20003

IIBM5550 대만

20004

x-cp20004

TeleText 대만

20005

x-cp20005

Wang 대만

20105

x-IA5

서유럽어(IA5)

20106

x-IA5-German

독일어(IA5)

20107

x-IA5-Swedish

스웨덴어(IA5)

20108

x-IA5-Norwegian

노르웨이어(IA5)

20127

us-ascii

US-ASCII

*

20261

x-cp20261

T.61

20269

x-cp20269

ISO-6937

20273

IBM273

IBM EBCDIC(독일)

20277

IBM277

IBM EBCDIC(덴마크-노르웨이)

20278

IBM278

IBM EBCDIC(핀란드-스웨덴)

20280

IBM280

IBM EBCDIC(이탈리아)

20284

IBM284

IBM EBCDIC(스페인)

20285

IBM285

IBM EBCDIC(영국)

20290

IBM290

IBM EBCDIC(일본어 가타카나)

20297

IBM297

IBM EBCDIC(프랑스)

20420

IBM420

IBM EBCDIC(아랍어)

20423

IBM423

IBM EBCDIC(그리스어)

20424

IBM424

IBM EBCDIC(히브리어)

20833

x-EBCDIC-KoreanExtended

IBM EBCDIC(한국어 확장)

20838

IBM-Thai

IBM EBCDIC(태국어)

20866

koi8-r

키릴 자모(KOI8-R)

20871

IBM871

IBM EBCDIC(아이슬란드어)

20880

IBM880

IBM EBCDIC(키릴 자모 러시아어)

20905

IBM905

IBM EBCDIC(터키어)

20924

IBM00924

IBM 라틴어-1

20932

EUC-JP

일본어(JIS 0208-1990 및 0212-1990)

20936

x-cp20936

중국어 간체(GB2312-80)

*

20949

x-cp20949

한국어(완성)

*

21025

cp1025

IBM EBCDIC(키릴 자모 세르비아어-불가리아어)

21866

koi8-u

키릴 자모(KOI8-U)

28591

iso-8859-1

서유럽어(ISO)

*

28592

iso-8859-2

중앙 유럽어(ISO)

28593

iso-8859-3

라틴어 3(ISO)

28594

iso-8859-4

발트어(ISO)

28595

iso-8859-5

키릴 자모(ISO)

28596

iso-8859-6

아랍어(ISO)

28597

iso-8859-7

그리스어(ISO)

28598

iso-8859-8

히브리어(ISO-Visual)

*

28599

iso-8859-9

터키어(ISO)

28603

iso-8859-13

에스토니아어(ISO)

28605

iso-8859-15

라틴어 9(ISO)

29001

x-Europa

유로파

38598

iso-8859-8-i

히브리어(ISO-Logical)

*

50220

iso-2022-jp

일본어(JIS)

*

50221

csISO2022JP

일본어(JIS-Allow 1 byte Kana)

*

50222

iso-2022-jp

일본어(JIS-Allow 1 byte Kana - SO/SI)

*

50225

iso-2022-kr

한국어(ISO)

*

50227

x-cp50227

중국어 간체(ISO-2022)

*

51932

euc-jp

일본어(EUC)

*

51936

EUC-CN

중국어 간체(EUC)

*

51949

euc-kr

한국어(EUC)

*

52936

hz-gb-2312

중국어 간체(HZ)

*

54936

GB18030

중국어 간체(GB18030)

*

57002

x-iscii-de

ISCII 데바나가리어

*

57003

x-iscii-be

ISCII 벵골어

*

57004

x-iscii-ta

ISCII 타밀어

*

57005

x-iscii-te

ISCII 텔루구어

*

57006

x-iscii-as

ISCII 아샘어

*

57007

x-iscii-or

ISCII 오리야어

*

57008

x-iscii-ka

ISCII 카나다어

*

57009

x-iscii-ma

ISCII 말라얄람어

*

57010

x-iscii-gu

ISCII 구자라트어

*

57011

x-iscii-pa

ISCII 펀잡어

*

65000

utf-7

유니코드(UTF-7)

*

65001

utf-8

유니코드(UTF-8)

top
:

▣  최선의 이벤트 기반 비동기 패턴 구현방법 - .NET/C# - 2011. 7. 18. 11:25

출처 : http://jinsoolife.tistory.com/35


이벤트 기반 비동기 패턴에서는 익숙한 이벤트와 대리자 의미를 사용하여 클래스에서 비동기 동작을 노출할 수 있는 효과적인 방법을 제공합니다. 이벤트 기반 비동기 패턴을 구현하려면 몇 가지 특정 동작 요구 사항을 준수해야 합니다. 다음 단원에서는 이벤트 기반 비동기 패턴을 따르는 클래스를 구현할 때 고려해야 할 요구 사항과 지침에 대해 설명합니다.



전체적인 개요를 보려면 이벤트 기반 비동기 패턴 구현을 참조하십시오.



다음 목록에는 이 항목에서 설명하는 최선의 방법이 표시됩니다.

  • 필요한 동작 보장

  • 완료

  • 완료된 이벤트 및 EventArgs

  • 작업 동시 실행

  • 결과 액세스

  • 진행률 보고

  • IsBusy 구현

  • 취소

  • 오류 및 예외

  • 스레딩 및 컨텍스트

  • 지침



이벤트 기반 비동기 패턴을 구현할 경우 클래스가 제대로 동작하고 클래스의 클라이언트가 이러한 동작을 신뢰할 수 있도록 충분히 보장해야 합니다.

 

 

완료



성공적으로 완료하거나 오류가 발생하거나 취소한 경우 MethodNameCompleted 이벤트 처리기를 항상 호출합니다. 응용 프로그램이 유휴 상태로 남아 완료될 수 없는 상황이 발생하면 안 됩니다. 비동기 동작 자체가 완료되지 않도록 설계된 경우에만 이 규칙이 적용되지 않습니다.

 

 

완료된 이벤트 및 EventArgs



별개의 MethodNameAsync 메서드에 대해 다음 디자인 요구 사항이 적용됩니다.

  • MethodNameCompleted 이벤트를 메서드와 같은 클래스에서 정의합니다.

  • AsyncCompletedEventArgs 클래스에서 파생되는 MethodNameCompleted 이벤트의 EventArgs 클래스와 관련 대리자를 정의합니다. 기본 클래스 이름은 MethodNameCompletedEventArgs 형식이어야 합니다.

  • EventArgs 클래스가 MethodName 메서드의 반환 값으로만 한정되도록 합니다. EventArgs 클래스를 사용할 때 개발자가 결과를 캐스팅하지 않도록 해야 합니다.

    다음 코드 예제에서는 이 디자인 요구 사항을 제대로 구현한 것과 잘못 구현한 것을 각각 보여 줍니다.



// Good design
private void Form1_MethodNameCompleted(object sender, xxxCompletedEventArgs e)
{
    DemoType result = e.Result;
}



// Bad design
private void Form1_MethodNameCompleted(object sender, MethodNameCompletedEventArgs e)
{
    DemoType result = (DemoType)(e.Result);
}

 

 

작업 동시 실행

  • 클래스가 여러 개의 동시 호출을 지원하는 경우 개발자가 userSuppliedState라는 개체 값 상태 매개 변수 또는 작업 ID를 가지는 MethodNameAsync 오버로드를 정의하여 각 호출을 개별적으로 추적할 수 있습니다. 이 매개 변수는 항상 MethodNameAsync 메서드의 시그니처에서 마지막 매개 변수여야 합니다.

  • 클래스에서 개체 값 상태 매개 변수 또는 작업 ID를 가지는 MethodNameAsync 오버로드를 정의하는 경우 해당 작업 ID의 작업에 대한 수명을 추적하고 이를 완료 처리기에 다시 제공해야 합니다. 이 작업에 도움을 줄 수 있는 도우미 클래스가 있습니다. 동시성 관리에 대한 자세한 내용은 연습: 이벤트 기반 비동기 패턴을 지원하는 구성 요소 구현을 참조하십시오.

  • 클래스에서 상태 매개 변수 없이 MethodNameAsync 메서드를 정의하고 여러 개의 동시 호출을 지원하지 않는 경우 이전 MethodNameAsync 호출이 완료되기 전에 MethodNameAsync를 호출하려고 하면 InvalidOperationException이 발생하도록 합니다.

  • 일반적으로 userSuppliedState 매개 변수 없이 MethodNameAsync 메서드를 여러 번 호출해서 처리 중인 작업이 여럿 있도록 하는 경우 예외가 발생하지 않습니다. 클래스에서 이러한 상황을 명시적으로 처리할 수 없는 경우 예외를 발생시킬 수 있지만 개발자는 이러한 구분할 수 없는 여러 콜백을 처리할 수 있습니다.

 

 

결과 액세스

 

 

진행률 보고

  • 가능하면 진행률 보고를 지원합니다. 이렇게 하면 개발자가 클래스 사용자에게 더 나은 응용 프로그램 경험을 제공할 수 있습니다.

  • ProgressChanged/MethodNameProgressChanged 이벤트를 구현할 경우 작업의 MethodNameCompleted 이벤트가 발생한 후 특정 비동기 작업에 대해 이러한 이벤트가 발생하지 않도록 합니다.

  • 표준 ProgressChangedEventArgs를 채우는 경우 ProgressPercentage가 항상 백분율로 해석될 수 있도록 합니다. 백분율이 정확할 필요는 없지만 백분율을 나타내야 합니다. 진행률 보고 메트릭이 백분율이 아니어야 하는 경우 ProgressChangedEventArgs 클래스에서 클래스를 파생하고 ProgressPercentage를 0으로 둡니다. 백분율 이외의 보고 메트릭을 사용하지 않는 것이 좋습니다.

  • 응용 프로그램 수명의 적절한 시기에 적절한 스레드에서 ProgressChanged 이벤트가 발생하도록 합니다. 자세한 내용은 스레딩 및 컨텍스트 단원을 참조하십시오.

 

 

IsBusy 구현

  • 클래스에서 여러 개의 동시 호출을 지원하는 경우 IsBusy 속성을 노출하지 마십시오. 예를 들어, XML Web services 프록시는 비동기 메서드에 대해 여러 개의 동시 호출을 지원하기 때문에 IsBusy 속성을 노출하지 않습니다.

  • IsBusy 속성은 MethodNameAsync 메서드를 호출한 후 MethodNameCompleted 이벤트가 발생하기 전까지 true를 반환해야 합니다. 그렇지 않으면 false를 반환해야 합니다. BackgroundWorkerWebClient 구성 요소는 IsBusy 속성을 노출하는 클래스의 예입니다.

 

 

취소

  • 가능하면 취소를 지원합니다. 이렇게 하면 개발자가 클래스 사용자에게 더 나은 응용 프로그램 경험을 제공할 수 있습니다.

  • 취소의 경우 AsyncCompletedEventArgs 개체에서 Cancelled 플래그를 설정합니다.

  • 결과에 액세스하려고 하면 작업이 취소되었음을 나타내는 InvalidOperationException이 발생하도록 합니다. 이러한 확인 작업을 수행하려면 AsyncCompletedEventArgs..::.RaiseExceptionIfNecessary 메서드를 사용합니다.

  • 취소 메서드를 호출하면 항상 성공적으로 반환되고 예외를 발생시키지 않도록 합니다. 일반적으로 클라이언트는 지정된 시간에 작업을 실제로 취소할 수 있는지 여부와 이전에 실행한 취소가 성공했는지 여부에 대한 알림을 받지 않습니다. 그러나 응용 프로그램은 완료 상태에 참여하기 때문에 취소가 성공하면 항상 알림을 받습니다.

  • 작업이 취소되면 MethodNameCompleted 이벤트를 발생시킵니다.

 

 

오류 및 예외

 

 

스레딩 및 컨텍스트

클래스가 제대로 작동하기 위해서는 ASP.NET 및 Windows Forms 응용 프로그램을 포함하는 지정된 응용 프로그램 모델에 대해 적절한 스레드 또는 컨텍스트에서 클라이언트의 이벤트 처리기를 호출하는 것이 중요합니다. 비동기 클래스가 모든 응용 프로그램 모델에서 제대로 동작할 수 있도록 AsyncOperationAsyncOperationManager라는 두 개의 중요한 도우미 클래스가 제공됩니다.

AsyncOperationManager에서 AsyncOperation을 반환하는 CreateOperation이라는 메서드 하나를 제공합니다. MethodNameAsync 메서드는 CreateOperation을 호출하고 클래스는 반환된 AsyncOperation을 사용하여 비동기 작업의 수명을 추적합니다.

진행률, 증분 결과 및 완료를 클라이언트에 보고하려면 AsyncOperation에서 PostOperationCompleted 메서드를 호출합니다. AsyncOperation은 클라이언트의 이벤트 처리기에 대한 호출을 적절한 스레드나 컨텍스트로 마샬링합니다.



AsyncOperation
AsyncOperationManager를 사용하여 비동기 작업을 사용할 수 있도록 설정하는 방법에 대한 자세한 내용은 연습: 이벤트 기반 비동기 패턴을 지원하는 구성 요소 구현을 참조하십시오.
  • 이상적으로 각 메서드 호출은 서로 독립적이어야 합니다. 공유 리소스를 포함하는 호출을 결합하지 마십시오. 호출 간에 리소스를 공유하려면 구현에서 적절한 동기화 메커니즘을 제공해야 합니다.

  • 클라이언트가 동기화를 구현해야 하는 디자인은 권장하지 않습니다. 예를 들어, 전역 정적 개체를 매개 변수로 받는 비동기 메서드가 있을 수 있습니다. 이러한 메서드를 동시에 여러 번 호출하면 데이터 손상이나 교착 상태가 발생할 수 있습니다.

  • 다중 호출 오버로드(시그니처의 userState)를 사용하여 메서드를 구현하는 경우 클래스에서 사용자 상태나 작업 ID 및 해당하는 보류 중 작업의 컬렉션을 관리해야 합니다. 여러 호출에서 컬렉션의 userState 개체를 추가 및 제거하므로 이 컬렉션을 lock 영역으로 보호해야 합니다.

  • 가능하거나 적절한 경우 CompletedEventArgs 클래스를 다시 사용할 수 있습니다. 이 경우 지정된 대리자와 EventArgs 형식이 하나의 메서드와만 관련된 것이 아니므로 메서드 이름 지정이 일관되지 않습니다. 그러나 개발자가 EventArgs의 속성에서 검색한 값을 캐스팅하도록 하는 것은 좋지 않습니다.

  • Component에서 파생되는 클래스를 만드는 경우에는 사용자가 직접 SynchronizationContext 클래스를 구현하고 설치하지 마십시오. 구성 요소가 아니라 응용 프로그램 모델이 사용되는 SynchronizationContext를 제어합니다.

  • 다중 스레딩을 사용할 경우 매우 심각하고 복잡한 버그에 노출될 위험이 있습니다. 다중 스레딩을 사용하는 솔루션을 구현하기 전에 관리되는 스레딩을 구현하는 최선의 방법을 참조하십시오.

http://msdn.microsoft.com/ko-kr/library/ms228974.aspx
top
:

▣  Debug와 Release모드의 차이 - .NET/C# - 2011. 6. 21. 13:25


프로젝트시 Debug에서 이상없이 실행되던 것이 Release로 컴파일하면 오류가 나는 경우
참고 사이트 : Http://sungod0.eglos.com3920875
 Debug mode vs Release mode

디버그 모드에서는 잘 돌아가는데 릴리즈 모드로 빌드해서 프로그램을 실행하면 뻑(?)이 나요. 왜 이럴까요?

이런 질문을 본적이 있거나 혹은 직접 경험해본 사람들이라면 이 버그를 잡는 고통을 잘 알것이다. 디버그와 릴리즈모드의 컴파일러 뒷단에서 일어나는 내용에 대해서 충분히 숙지 하지 못하고 있다면 이런 류의 버그를 잡기란 여간 까다로운 것이 아니다.

Visual Studio의 디버그 모드와 릴리즈 모드의 차이점은 무엇이고 어떤 일들이 일어나는지 본인의 경험, 웹상에서 찾은 정보들을 정리해두어 이런 버그로 고생하는데 도움(?)이 되었으면 한다.

 

Check List
•Pointer
초기화 되지 않은 포인터의 경우 디버그모드에서는 임의값 0xCD로 초기화를 수행하지만 릴리즈에서는 초기화를 수행하지 않는다. 디버그 모드에서 컴파일러 옵션을 조정하여 초기화 하지 않은 포인터 변수를 사용하는것을 예방 할 수 있다. /GZ 컴파일러 옵션은 기본적으로 VC++ 프로젝트 셋팅에서 기본값이 아니므로 필요하다면 추가해서 초기화 되지 않는 포인터의 값을 0xCC로 채우도록 해줘야 한다. /GZ 컴파일러 옵션의 가장 큰 목적은 초기화 하지 않은 메모리 변수의 값을 0xCCCCCCCC로 채워서 디버깅중에 개발자가 초기화 하지 않은 값임을 알 수 있도록 하는것이다.
◦디버그모드에서 deallocator에 의해 해제된 메모리에 채워지는 값은 0xDD 이다.
•Heap
디버그 모드에서 힙영역에 메모리를 할당하게 되면 guard byte( 0xFD로 초기화 )를 추가적으로 할당하여 가장 흔하게 범하는 zero-base의 arrary 인덱스를 잘못 계산하여 경계를 벗어난 영역을 접근하거나 지우려고 하는 코드를 작성했다고 하더라도 디버그 모드에서는 크래쉬가 발생하지 않을 수 있다. 이런 잠재적인 버그를 가진 프로그램을 릴리즈 모드에서 실행시키게 되면 크래쉬가 발생하게 된다.
•ASSERT
ASSERT 구문은 디버그 모드에서는 공백으로 대체되어지는 점을 잊고 아래와 같이 쓰게 되는 경우 이 코드는 릴리즈에서는 공백으로 대체되어 실제로 체크를 할 수 없게 된다.
ASSERT (OpenMyWindow () != NULL);위의 코드를 다음과 같이 바꾸게 되면 디버그와 릴리즈 모드 모두 정상적으로 동작하게 된다.
hWND = OpenMyWindow();ASSERT (hWND != NULL);이런 체크를 릴리즈에서도 하고 싶다면 VERITY 매크로를 사용하도록 하자.
•Prototypes 사용자 정의 메시지 처리를 위해 ON_MESSAGE 매크로를 사용중이라면 메시지 핸들러의 원형을 요구하는 타입에 정확하게 맞게 선언해줘야 한다. 디버그 모드에서는 원형에 일치하지 않더라도 컴파일러가 수정하여 동작하도록 만들어줘 버그를 발견하기 힘들게 만든다.
afx_msg LRESULT <class>::OnMyMessage (WPARAM wParam, LPARAM lParam);•Optimization Max Speed 옵션은 속도 최적화에 촛점을 맞추고 있기 때문에 최적화 과정에서 안전하지 않을수 있다. 기본적으로 릴리즈 모드에서는 Maximize Speed 옵션이 기본이지만 안전하게 속도 최적화를 보장하는 Minimize Size를 추천한다. 그리고, #pragma 지시자를 사용하여 특정 영역의 옵션을 설정 할 수 있다는것을 기억하자.
#pragma optimize("", off)// some code here #pragma optimize("", on)MSDN에서 권고하는 릴리즈 빌드 문제 해결
•ASSERT 문 검사
◦CheckList의 ASSERT
•디버그 빌드를 사용한 메모리 덮어쓰기 확인
1.InitInstance 함수의 맨 처음 부분에 다음 줄을 추가합니다. 이렇게 하면 디버그 메모리 할당자가 모든 할당된 메모리 주위에 보호 바이트를 배치합니다. 그러나 이 보호 바이트의 변경 여부(변경되었으면 메모리 덮어쓰기가 발생했음)를 확인하지 않으면 보호 바이트는 아무런 소용이 없습니다. 보호 바이트의 변경 여부를 확인하면 버퍼가 제공되어 메모리 덮어쓰기를 해결할 수 있습니다.

afxMemDF |= checkAlwaysMemDF;checkAlwaysMemDF 변수를 설정하면 MFC에서는 new 또는 delete가 호출될 때마다 AfxCheckMemory 함수를 호출하게 됩니다. 메모리 덮어쓰기가 감지된 경우에는 다음과 같은 TRACE 메시지가 생성됩니다.

Damage Occurred! Block=0x5533이러한 메시지가 표시되는 경우에는 코드를 단계별로 실행하여 손상된 부분을 확인해야 합니다. 메모리 덮어쓰기가 발생한 부분을 보다 정확하게 구별하려면 사용자가 AfxCheckMemory를 명시적으로 호출하면 됩니다. 예를 들면 다음과 같습니다.

ASSERT(AfxCheckMemory());    DoABunchOfStuff();ASSERT(AfxCheckMemory());첫 번째 ASSERT는 성공하고 두 번째 ASSERT는 실패하는 경우에는 두 호출 사이의 함수에서 메모리 덮어쓰기가 발생했을 가능성이 큽니다.

응용 프로그램의 특성에 따라 afxMemDF를 사용하면 프로그램 실행이 너무 느려져서 테스트조차 수행할 수 없는 경우도 있습니다. 왜냐하면afxMemDF 변수는 new 및 delete가 호출될 때마다 AfxCheckMemory가 호출되도록 하기 때문입니다. 이 경우에는 위의 예제와 같이 AfxCheckMemory( ) 호출을 분산시켜야 하며, 이러한 방법으로 메모리 덮어쓰기를 구별해야 합니다.

•릴리스 빌드에 대한 디버그 정보 생성 활성화
1.프로젝트의 속성 페이지 대화 상자를 엽니다. 자세한 내용은 Visual C++ 프로젝트 속성 설정을 참조하십시오.
2./Z7 또는 /Zi를 활성화합니다.
3./INCREMENTAL:NO를 선택합니다.
4./DEBUG:Yes를 선택합니다.
5./OPT:REF를 선택합니다.
6./OPT:ICF를 선택합니다.
◦이제 릴리스 빌드 응용 프로그램을 디버깅할 수 있습니다. 문제를 찾으려면 오류가 발생한 부분을 찾을 때까지 코드를 단계별로 실행하거나, Just-In-Time 디버깅을 사용하여 올바르지 않은 매개 변수 또는 코드를 확인합니다.

프로그램이 디버그 빌드에서는 작동하지만 릴리스 빌드에서 작동하지 않으면 소스 코드에서 컴파일러 최적화 중 하나에 결함이 있는 경우일 수 있습니다. 문제를 격리하려면 문제의 원인이 되는 최적화와 파일을 찾을 때까지 각 소스 코드 파일에 대해 선택한 최적화를 비활성화해야 합니다. 예를 들어, 파일을 두 그룹으로 나누고 한 그룹에서 최적화를 비활성화한 다음 문제가 파일 하나에서만 발생할 때까지 각 그룹을 계속 나눌 수 있습니다.

디버그 빌드에서 그러한 버그를 노출시키려면 /RTC를 사용합니다.

•메모리 덮어쓰기 확인
힙 조작 함수 호출 시 액세스 위반이 발생되면 프로그램이 힙을 손상시켰을 가능성이 있습니다. 이러한 경우의 일반적인 증상은 다음과 같습니다.
Access Violation in _searchseg_heapchk 함수는 디버그 빌드와 릴리스 빌드 모두에서(Windows NT에만 해당) 런타임 라이브러리 힙의 무결성을 확인하는 데 사용할 수 있습니다. _heapchk는 AfxCheckMemory 함수를 사용하여 힙 덮어쓰기를 확인하는 것과 같은 방법으로 사용할 수 있습니다. 예를 들면 다음과 같습니다.
if(_heapchk()!=_HEAPOK)   DebugBreak();이 함수가 실패하는 경우에는 힙이 손상된 시점을 확인해야 합니다.
Reference
•Debugging Release Mode Problems
•Debug vs Release mode differences when storing a delegate in a hashtable
•My app works in debug build, but crashes in release. What's the difference between the two?
•joelonsoftware "Problems with Release build (but not Debug)"
•HOWTO: 릴리즈 모드로 build 된 프로그램의 디버깅
tag: debug, release


  

========================================================================================================

mastojun.net/181
http://www.jongkok4.net/10

-릴리즈 모드
프로그램을 배포하기 위해 컴파일 하는 모드
-초기화 하지 않는다.
-같은 문자열 상수라도 서로다른 공간에 할당한다.
-디버깅정보를 삽입하지 않고 코드를 최적화하여 실행 파일 크기를 최대한 줄여준다.
-속도나 크기면에서 월등이 유리하다(메모리 점유율로 낮아지고 실행도 빨라짐)
-더이상 현재버전에서 내결함성이나 문제점들을 발견할 수 없었을때 빌드하여 주는 모드


-디버깅 모드
-컴파일시 들어가는 디버깅에 필요한 자질구리한 정보를 뺀 알짜 프로그램만 쏙 뽑아냄
-실행파일에 디버깅 정보를 삽입하여 언제든지 디버깅을 할 수 있도록 하며 Debug서브 폴더에 실행파일을 만들어준다.
-디버깅정보가 들어가 있기때문에 실행파일 상태를 확인할수 있다.
-디버그에 필요한 정보들을 실행시 계속 체크함으로써 속도가 느림


-디버그 빌드와 릴리즈 빌드에서 서로 실행 결과가 다른 경우?
특기 디버그 빌드에서는 괜찮은데 릴리즈 빌드에서만 오류가 발생하여 프로그램이 죽는 경우가 있는데
이런 경우는 대부분 메모리가 깨진 경우에 발생한다. 두 모드에서 동적으로 메모리를 할당하면 힙 영역에
요청한 크기만큼 메모리를 할당 받게 되는데 그 초기값이 다르다.

-릴리즈 모드와 디버깅모드의 차이점은?
디버깅 정보를 실행코드 안에 넣느냐 안넣느냐임
즉 디버거 모드로 컴파일하게되면 실행상태에서 추적할수 있는 정보가 실행파일 안에 들어가게 됨
그래서 용량이 커점
릴리즈는 디버깅 정보없어 순수한 소스코드자체의 기능만 컴파일되어 실행파일로 만들어짐

top
:


articles
recent replies
recent trackbacks
notice
Admin : New post