성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] How can I tell whether two programs...
[정성태] The case of the fail-fast crashes c...
[정성태] Creating Docker multi-arch images f...
[정성태] BinaryFormatter removed from .NET 9...
[정성태] Extending the Windows Shell Progres...
[우광현] 와..... 범위를 잡았으니 클라이언트가 해당 범위를 확인해본다...
[정성태] 딱히, 그것 이상으로 더 설명할 내용이 없습니다. 동적 포...
[정성태] If Windows 3.11 required a 32-bit p...
[정성태] What is a hard error, and what make...
[괴물신인] 질문작성자인데 이 글을 이제봤네요 ㄷㄷ 이 글처럼 타입별로 인...
글쓰기
제목
이름
암호
전자우편
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# Thread가 Running 상태인지 아는 방법</h1> <p> Thread가 실행 상태인지 어떻게 알 수 있을까요? 가령 Thread.IsAlive가 왠지 그럴 것 같습니다. 테스트를 해볼까요?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > class Program { static void Main(string[] args) { Thread t = new Thread(threadFunc); t.Start(); <span style='color: blue; font-weight: bold'>bool alive = t.IsAlive;</span> Console.WriteLine(alive); } private static void threadFunc(object obj) { Console.WriteLine("TEST: " + obj); } } </pre> <br /> 위의 코드에서 Console.WriteLine에 BP를 걸고 비주얼 스튜디오를 시작한 후 Ctrl+Alt+H 단축키를 눌러 Threads 창을 띄우면 결과를 알 수 있습니다. t.IsAlive는 true이지만 t 스레드는 생성조차 되지 않은 것을 볼 수 있습니다. 즉 t.IsAlive는 Thread 객체가 생성된 후 Start 메서드가 불린 순간부터 무조건 true이고 그 이후 스레드 종료가 되어야 false로 바뀌는 것입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 다음 후보로 Thread.ThreadState는 어떨까요? ThreadState enum 값에는 분명히 Running이 있으니 다음과 같이 테스트할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > class Program { static void Main(string[] args) { Thread t = new Thread(threadFunc); t.Start(); bool alive = t.IsAlive; <span style='color: blue; font-weight: bold'>bool running = t.ThreadState == ThreadState.Running;</span> Console.WriteLine(alive); } private static void threadFunc(object obj) { Console.WriteLine("TEST: " + obj); } } </pre> <br /> 그런데 이것 역시 BP를 걸어 테스트해보면 실제 스레드 생성 유무와 상관없이 Thread.Start 이후 Running 상태임을 알 수 있습니다. 설령 이 필드가 그 의미 그대로 Running이라고 해도 문제입니다. 왜냐하면 필드의 값이 0이기 때문입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > [ComVisible(true)] [Flags] public enum ThreadState { <span style='color: blue; font-weight: bold'>Running = 0,</span> StopRequested = 1, SuspendRequested = 2, Background = 4, Unstarted = 8, Stopped = 16, WaitSleepJoin = 32, Suspended = 64, AbortRequested = 128, Aborted = 256 } </pre> <br /> 따라서 Thread.IsBackground = true; 같은 식으로 설정해 버리면 Running을 알아낼 방법이 없습니다. 왜냐하면 다음의 조건도 false이고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > bool running = t.ThreadState == ThreadState.Running; // ThreadState == 4 (Background)이므로. </pre> <br /> 그렇다고 다음과 같이 해도 Running이 0이므로 항상/무조건 true가 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > bool running = (t.ThreadState & ThreadState.Running) == ThreadState.Running; </pre> <br /> <hr style='width: 50%' /><br /> <br /> 결국 가장 적당한 방법은 스레드 함수가 실행하는 초기/후기에 EventWaitHandle 등을 이용해 그 사실을 알려주는 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void Main(string[] args) { EventWaitHandle started = new EventWaitHandle(false, EventResetMode.ManualReset); EventWaitHandle exited = new EventWaitHandle(false, EventResetMode.ManualReset); Thread t = new Thread(threadFunc); t.Start((started, exited)); bool threadStarted = started.WaitOne(0); bool threadExited = exited.WaitOne(0); } private static void threadFunc(object obj) { var events = (System.ValueTuple<EventWaitHandle, EventWaitHandle>)obj; { events.Item1.Set(); Console.WriteLine("TEST: " + obj); events.Item2.Set(); } } </pre> <br /> 또는 DONT_USE_InternalThread 등의 내부 필드를 이용해,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET System.Threading.Thread 개체에서 Native Thread Id를 구할 수 있을까? ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1244'>http://www.sysnet.pe.kr/2/0/1244</a> </pre> <br /> 그에 상응하는 스레드를 Process.GetCurrentProcess().Threads에서 찾는 방식을 비공식적으로 고려할 수 있습니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1314
(왼쪽의 숫자를 입력해야 합니다.)