본문으로 바로가기

C# 무한루프에 딜레이 주기

category Coding/C# 2016. 2. 24. 19:38
반응형

 

 

 

사건 개요:

 

수많은 삽질과 노고 끝내 탄생시킨 나의 야심찬 프로젝트 MC_warp가 완성 단계에 이르렀을 때쯤,

테스트를 해봤더니 CPU점유율이 뜨헉! 이끄이끄한 사태 발생.

높아도 너무 높다. 다른 프로그램에 렉이 발생한다...

몇번에 위기를 넘겨가며 원하는 모든 기능을 구현했건만 이대로 물거품이 되게 내버려 둘 순 없다. 원인을 찾자.

 

원인은 어렵지 않게 찾았다.

무한루프에 딜레이를 줄 명목으로 DoEvents를 너무 길게준것.

길어봐야 1초지만... 이것은 언제까지나 내 기준. CPU에게는 고통 이었다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static DateTime Delay(int MS)
        {
            DateTime ThisMoment = DateTime.Now;
            TimeSpan duration = new TimeSpan(0, 0, 0, 0, MS);
            DateTime AfterWards = ThisMoment.Add(duration);
 
            while (AfterWards >= ThisMoment)
            {
                System.Windows.Forms.Application.DoEvents();
                ThisMoment = DateTime.Now;
            }
 
            return DateTime.Now;
        }

단일/멀티 스레드에서 쓰기가 간편하고 효과, 안정성 모두 좋다. Delay(몇밀리초); 하면 그만이다.

하지만 이것은 우리들 입장에서 딜레이 일뿐, CPU에게는 상당한 고역이다.

무한루프에 이것으로 딜레이를 주었기때문에 loop안의 내용을 처리하는 것보다 딜레이에

더 많은 자원을 소모하게 된 우스운 꼴이 되버린 것이다.

 

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

 

 

 

사건 해결:

 

1
2
3
4
5
6
7
8
while (true)
{
    switch (메소드)
    {
        case 겁나많음:
    }
    Thread.sleep(1000);
}

단일 스레드 폼이기 때문에 이렇게 했다가는 1초만 자는게 아니라 영원히 자버리게 된다.

멀티 스레드로 바꾸기엔 너무 멀리왔고 어설픈 스레드 관리로 안정성이 깨질 우려가 있다.

 

그러던차에 눈에 쏙 들어온 놈, Timer

 

 

Tick 이벤트 자체가 반복문이 아니던가.

while문이 드문드문 실행되게 하는것은 Timer로 간단하게 끝냈지만,

case중 실행시간이 긴놈이 걸려버리면 끝나버리기도 전에 다음 Tick이 중복 실행되는 치명상을 입게 된다.

이것을 bool타입 변수로 해결 해보자.

 

 

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
32
33
34
35
36
bool sCheck = false;
 
private void 시작버튼(object sender, EventArgs e)
{
    sCheck = true;
    timer1.Enabled = true;
}
 
private void 중지버튼(object sender, EventArgs e)
{
    sCheck = false;
    timer1.Enabled = false;
}
 
private void timer1_Tick(object sender, EventArgs e)
{
    스위치문();
}
 
private void 스위치문()
{
    if (sCheck == true)
    {
        timer1.Enabled = false// case실행중 Tick의 접근을 막겠다.
    }
 
    switch (메소드)
    {
        case 겁나많음:
    }
 
    if (sCheck == true) // case실행중 중지버튼이 눌러지면 Tick을 끝내겠다.
    {
        timer1.Enabled = true;
    }
}

이상 사건 해결 완료.

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


출처 : http://11cc.tistory.com/5

반응형

'Coding > C#' 카테고리의 다른 글

C# Json 설치  (0) 2015.11.18
Multipart  (0) 2015.11.18
C# 디시인사이드 유동닉 댓글달기  (2) 2015.11.18
Regex 그룹명 붙이기  (0) 2015.11.17
Webbrowser 에서 Proxy 설정하기  (0) 2015.11.13