Development Tip

C# UI 작업하면서 Delay 주기

MoonLight314 2024. 2. 14. 09:46
728x90

안녕하세요, MoonLight입니다.

오늘은 C#에서 Thread 작업 중에 UI가 먹통이 되지 않으면서 Delay를 줄 수 있는 방법을 2가지 소개해 드릴까 합니다.

Delay를 주는 함수로써 Thread.Sleep()이 대표적인데, 이 녀석은 Delay 동안 Blocking된다는 치명적인 단점이 있습니다.

Blocking되버리면, UI가 먹통이 되버리기 때문에 사용자의 짜증을 유발할 수가 있습니다.

이런 상황은 절대로 일어나선 안되겠죠.

이를 방지할 수 있는 방법으로 제가 주로 사용하는 방법은 2가지가 있는데요, 하나씩 알아보겠습니다.

1. Event 처리하면서 Delay하기

아래 Code와 같은 Delay함수를 만듭니다.

정해진 시간만큼 Delay하고, System.Windows.Forms.Application.DoEvents()를 Call하면서 UI Event도 처리하는

살짝 무식한(?) 방법입니다.

private static DateTime Delay(int MS)
{
    DateTime Current = DateTime.Now;
    TimeSpan Delay = new TimeSpan(0, 0, 0, 0, MS);
    DateTime StopTime = Current.Add(Delay);
    while (StopTime >= Current)
    {
        System.Windows.Forms.Application.DoEvents();
        Current = DateTime.Now;
    }
    return DateTime.Now;
}

 

2. await Task.Delay() 사용하기

위의 Code보다 비동기 작업에 걸맞다고 생각하는 Delay방식입니다.

await Task.Delay(<Delay할 시간. ms 단위>);

먼저 Task.Delay() 함수는 Thread.Sleep()과는 다르게, 비동기 방식으로 작동하는 함수이며, Non-Blocking입니다.

여기까지는 일반적인 설명이며 쉽게 이해가 됩니다.

문제는 Task.Delay() 앞에 사용된 await라는 Keyword와 Task.Delay()가 사용된 함수에 붙어야 하는 async Keyword입니다.

먼저 async Keyword는 아래와 같이 Method 선언시에 이름앞에 붙입니다.

private async void button1_Click(object sender, EventArgs e)

이렇게 되면 해당 Method는 비동기 Method가 되고, Method 내에서 await Keyword를 사용할 수 있습니다.

await는 await 다음에 오는 Method가 끝나기를 기다리라는 의미이지만, Non-Blocking입니다.

await는 다음에 오는 Method가 작업을 완료할 때까지 기다리며 해당 Method는 나머지 부분은 Blocking되지만, 호출자에게 즉시 제어를 넘깁니다.

따라서 전체적인 흐름은 Non-Blocking되는 것처럼 되는 것입니다.

이를 UI 처리와 연관해서 생각해 보면, 우리가 어떤 작업을 하면서 Delay를 주고는 싶은데, UI 반응성은 그대로 유지하고 싶다면 await Task.Delay를 사용하는 것이 더 훌륭한 방법이라는 의미입니다.

도움이 되셨기를 바랍니다.

그럼, 다음에 다음에 또 만나요~!

728x90