성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Roll A Lisp In C - Reading ; https...
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
글쓰기
제목
이름
암호
전자우편
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'>C# - 프로세스(EXE) 수준의 Singleton 개체 생성</h1> <p> 운영체제에 의해서 프로세스 격리가 제공되는 것을, 닷넷은 다시 프로세스 내부를 AppDomain이라는 단위로 격리시키고 서로 간의 직접 접근이 불가능하도록 만들었습니다.<br /> <br /> 그래서, Native 언어(예: C/C++)에서는 static으로 singleton을 만들었던 것을 닷넷에서는 static으로 지정했다고 프로세스 전역적으로 한 개만 존재하지는 않습니다, AppDomain 별로 존재하는 것이지.<br /> <br /> 이에 대한 해결책을 다음의 글에서 제공하고 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Cross AppDomain Singleton ; <a target='tab' href='http://ingebrigtsen.info/2007/05/18/cross-appdomain-singleton/'>http://ingebrigtsen.info/2007/05/18/cross-appdomain-singleton/</a> </pre> <br /> 근데, 코드가 별로 마음에 안 듭니다. ^^ Interop DLL이 별도로 추가된다는 것은 관리적인 요소만 하나 더 늘리게 되는 요인이 됩니다. 그래서, 아래의 방법을 곁들이면 더 좋습니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 레지스트리 등록 및 Interop DLL 없이 COM 개체 사용하는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1180'>http://www.sysnet.pe.kr/2/0/1180</a> </pre> <br /> <a name='icorruntimehost'></a> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public class CrossAppDomainSingleton<T> : MarshalByRefObject where T : new() { ...[생략]... private static AppDomain GetAppDomain(string friendlyName) { IntPtr enumHandle = IntPtr.Zero; ICorRuntimeHost host = null; try { <span style='color: blue; font-weight: bold'>host = Utility.CoCreateInstance("{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}") as ICorRuntimeHost;</span> if (host == null) { return null; } host.EnumDomains(out enumHandle); object domain = null; while (true) { host.NextDomain(enumHandle, out domain); if (domain == null) { break; } AppDomain appDomain = (AppDomain)domain; if (appDomain.FriendlyName.Equals(friendlyName)) { return appDomain; } } } finally { host.CloseEnum(enumHandle); Marshal.ReleaseComObject(host); host = null; } return null; } ...[생략]... } </pre> <br /> 지면(?) 관계상 <a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=752&boardid=331301885'>ICorRuntimeHost 등의 구현은 이 글의 첨부 파일로 참고</a>하시면 됩니다.<br /> <br /> 그나저나, 어쩔 수 없이 프로세스 수준의 Singleton을 사용해야 하지만 성능 손실은 과연 어느 정도일까요? 이를 위해 다음과 같이 테스트 코드를 작성해 봤습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public static class NonSingleton { static bool _test = true; public static bool Test { get { return _test; } } } public class Singleton : CrossAppDomainSingleton<Singleton> { bool _test = true; public bool Test { get { return _test; } } } class Program { static void Main(string[] args) { CheckTime(false, 1); // JIT 컴파일 시간을 배제하기 위해. CheckTime(true, 1000000); } private static void CheckTime(bool outputResult, int loopCount) { Stopwatch st = new Stopwatch(); st.Start(); int inc = 0; for (int i = 0; i < loopCount; i++) { if (NonSingleton.Test == true) { inc++; } } st.Stop(); if (outputResult == true) { Console.WriteLine(st.ElapsedMilliseconds); } System.Diagnostics.Trace.WriteLine(inc); st.Start(); inc = 0; Singleton singleton = Singleton.Instance; for (int i = 0; i < loopCount; i++) { if (singleton.Test == true) { inc++; } } st.Stop(); if (outputResult == true) { Console.WriteLine(st.ElapsedMilliseconds); } System.Diagnostics.Trace.WriteLine(inc); } } </pre> <br /> Release 빌드 후 테스트 결과는 다음과 같이 나왔습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 10,000 번 호출 NonSingleton: 0ms 10,000 번 호출 Singleton: 4ms 100,000 번 호출 NonSingleton: 0ms 100,000 번 호출 Singleton: 45ms 1,000,000 번 호출 NonSingleton: 1ms 1,000,000 번 호출 Singleton: 454ms 10,000,000 번 호출 NonSingleton: 19ms 10,000,000 번 호출 Singleton: 4539ms </pre> <br /> 거의 200배가 넘게 느린 결과를 볼 수 있는데요. 무척 느리다 싶지만 이런 유의 테스트가 현실로 왔을 때는 재미있게 해석될 수 있습니다. 예를 들어, 1초에 10,000번 호출된다고 가정했을 때 도메인간 호출이 겨우 4ms 더 시간이 걸릴 뿐이므로 그다지 나쁜 결과는 아니라는 것입니다.<br /> <br /> ** 주의할 점은, 이는 호출 간의 속도 저하일 뿐 마샬링이 복잡해지면 더욱 느려질 수 있다는 사실!!!<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1635
(왼쪽의 숫자를 입력해야 합니다.)