2024. 7. 23. 12:46ㆍC#
안녕하세요. 진득 코딩입니다. 개발을 하면서 직접 개발하는 것도 어렵지만 다른 사람의 코드를 해석하는 것도 굉장히 어려웠던 기억이 있습니다. 이번 시간에는 다른 사람이 구현한 코드를 분석해보는 시간을 가져보도록 하겠습니다.
실행해보기

해당 코드를 실행해보면 먼저 Form1이 나오게 됩니다. 그리고 player 수를 설정할 수있고 시작 버튼도 보실 수 있습니다. 이러한 텍스트와 버튼 밑에는 textBox를 보실 수있습니다.


필자는 player 수를 3으로 지정하였습니다. 시작 버튼을 누르게 되면 오른쪽에 플레이어의 수만큼 바가 생기게 되고 각각의 쓰레드가 실행되는 것을 확인하실 수 있습니다. 실행이 끝난 스레드는 textBox에 플레이어 이름과 함께 완주를 했다고 문구가 나오게 됩니다.
솔루션 탐색기 살펴보기

솔루션 탐색기를 살펴보면 해당 코드는 두 가지 Form을 사용한 것을 알 수 있습니다. 처음 실행했을 때 Form1이라는 창이 뜬 것을 봤을 때 기본적으로 Form1이 나오고 시작을 눌렀을 때 나오는 바들은 play.cs로 구현한 것을 짐작할 수 있습니다.
play.cs 살펴보기

일단 namespace는 _26_Thread로 설정하였고 partial class를 이용하여 Form과 같은 클래스를 사용하는 것을 알 수 있습니다. delegate로 delMessage를 선언하였습니다. 해당 메서드는 변수처럼 사용할 수 있으며 두 가지의 매개변수를 가지게 됩니다. eventdelMessage는 이벤트의 타입입니다. 여기서는 앞에서 선언한 delMessage 델리게이트 타입을 사용합니다. _strPlayerName은 player들의 이름을 초기화해주는 것으로 보이고 StrPlayerName을 이용하여 직접적으로 _strPlayerName에 접근하지 못하도록 은닉성을 추가해주었습니다. 추가로 Thread를 _thread로 선언해주었습니다.


생성자는 오버로딩하여 기본 생성자와 플레이어 이름을 매개변수로 받는 생성자가 있습니다. 플레이어 이름을 받는 생성자에서는 받아온 이름을 바에 있는 PlayerName이라는 부분에 전달하여 어떤 플레이어의 바인지 알려줍니다. fThreadStart 메서드는 스레드들이 시작되는 메서드로 보입니다. _thread에 Run이라는 메서드를 담아서 _thread.Start()를 이용하여 스레드들이 시작되는 것으로 보입니다.

시작하자마자 선언한 ivar는 바에 있는 %를 의미합니다. rd로 랜덤 함수를 가져와서 요청한 Thread에 있는 ivar에 랜덤으로 더해주어 바가 점점 찰 수 있도록 하였습니다.
while문은 바가 가득 차게되어 100이 되면 빠져나와서 eventdelMessage를 실행하게 됩니다. if문을 이용하여 invokeRequired를 사용하여 요청한 Thread가 현재 main Thread에 있는 control에 엑세스할 수 있는지 확인합니다. this.Invoke를 사용하여 UI 스레드에서 실행해야 할 작업을 안전하게 호출합니다.
내부적인 함수를 살펴보면 rd.Next()를 사용하여 ivar에 1~10까지의 숫자를 랜덤으로 넣어주고 100이 넘어가게 되면 바가 100프로 다 찼다고 처리하고 그게 아니라면 원래 있던 value에 할당된 랜덤 숫자를 더해줍니다.
이렇게 처리된 value를 lblProcess.Text를 사용하여 진행 상황 표시에 있는 %에 표시해줍니다. this.Refresh를 사용하여 컨트롤에 즉시 업데이트해 바에 즉각적으로 진행상황이 표시되도록 처리한 것으로 보입니다.
처리속도가 너무 빠르기 때문에 sleep을 사용하여 너무 빨리 처리되지 않도록 한 것으로 보입니다.
Form1 살펴보기

먼저 enumPlayer에 플레이어들의 이름을 먼저 초기화해줍니다. 또한 locationX와 Y를 선언하여 생성자에서 _locationX와 locationY로 받습니다.


위 생성자 부분과 해당 메서드 사이에 버튼 클릭하는 이벤트가 있지만 그 함수에서 해당 메서드를 호출하기 때문에 해당 메서드부터 살펴보도록 하겠습니다. 해당 메서드는 시작 버튼을 눌렀을 때 추가되는 메세지를 할당해주는 메서드입니다. 먼저 위 while문에서처럼 Invoke를 이용하여 UI 스레드에서 실행해야 할 작업을 안전하게 호출해주고 sender이 object 타입이기 때문에 play로 캐스팅(형 변환)해줍니다. as를 사용하게 되면 형변환이 불가능했을 때 오류가 나지 않고 null을 반환하기 때문에 프로그램을 실행할 때 좀 더 안정적입니다.
lboxResult는 Form1에 있는 결과가 나오는 결과창에 출력이 됩니다. 해당 화면에 출력될 아이템인 플레이어 이름과 텍스트를 아이템에 추가해주게 됩니다. return 0을 해서 초기화된 lboxResult에 아이템들을 넣어주게 됩니다.

마지막으로 시작 버튼을 눌렀을 때의 이벤트를 살펴보도록 하겠습니다. 위에서 선언해준 가로 변수는 Size.Width를 사용하여 할당해주고 Y는 그냥 _locationY로 for문으로 들어가게 됩니다.
for문에서는 플레이어의 수만큼 for문이 돌아가게 되고 플레이어들의 이름을 매개변수로 갖는 play 클래스를 타입으로 갖는 pl을 인스턴스해줍니다. 또한 Point라는 인스턴스에 x는 그대로 넣어주고 y는 for문에 따라 1씩 증가시켜 세로로 잘 정렬될 수 있도록 위치시켜줍니다. pl.eventdelMessage를 실행하고 거기에서 할당된 아이템들이 들어가게 됩니다. pl.show()가 실행되면서 form1 옆에 각 플레이어들의 진행도를 나타내는 바가 보이게 됩니다. 마지막으로 pl.fThreadStart() 메서드가 실행되면서 스레드들이 실행되게 됩니다.
이번 시간에는 다른 사람이 만든 코드를 살펴보는 시간을 가져보았습니다. 협업을 할 때에 다른 사람의 코드를 필수적으로 보기 때문에 이렇게 다른 사람의 코드를 해석하는 시간도 굉장히 유익한 시간이었습니다. 이번 포스팅은 여기까지입니다. 끝까지 봐주셔서 감사합니다.😀
'C#' 카테고리의 다른 글
[C#] 데이터 집합을 다루는 컬렉션을 알아보자 (0) | 2024.07.25 |
---|---|
[C#] try-catch로 예외 처리하는 법을 알아보자 (0) | 2024.07.23 |
[C#] 정적 메소드와 값을 참조하는 ref, out을 알아보자 (0) | 2024.07.18 |
[C#] 오버 로딩과 오버 라이딩에 대해 알아보자 (0) | 2024.07.17 |
[C#] 좀 더 심화된 C# 문법을 알아보자 (2) | 2024.07.16 |