티스토리 뷰

일반적인 GUI Application과 동일하게 Winform 또한 UI Thread가 MainThread 역할을 하며, 해당 Thread는 SingleThread 방식으로 돌아간다.

 

UI Thread는 기본적으로 Loop를 돌면서 MessageQueue에 담긴 Message를 가져오고, Handler에 전달하는 역할을 한다.

이때 Handler에서 딜레이가 오래 발생할 경우 MessageQueue에 담긴 다음 Message를 실행하지 못하므로, UI 프리징 현상이 발생 한다.

 

이러한 UI 프리징 현상을 방지하기 위해 시간이 오래 걸리는 작업은 별도의 Thread를 생성하여 처리한 후 결과만 UI에 반영하도록 개발 해야한다. BackgroundWorker, Thread, Task, AsyncCallBack 등 개인의 스타일에 따라 여러 방법이 있지만 여기서는 Task를 사용한 방법을 소개한다.

(어렵지 않은 코드이므로, 구현된 코드와 간단한 주석으로 구문별 설명을 대체 한다.)

 

1. 전역에서 사용할 TaskUtil Class 생성

- 매개변수로 넘어온 Action의 예외 체크를 위한 내부 Action 처리

    public class TaskUtil
    {
        public static Task Start(Action action)
        {
            Action param = () =>
            {
                try
                {
                    action();
                }
                catch (Exception e)
                {
                    Logger.Error(e);
                }
            };
            return Task.Factory.StartNew(param);
        }
    }

 

2. UI 코드에서 Task를 이용한 무거운 작업 실행 및 결과 반영

- CrossThread 에러를 피하기 위해 Invoke 처리하여 UI에 접근

- 딜레이 발생 후 해당 UI의 Dispose상태 확인

 

            TaskUtil.Start(() =>
            {
                // 5초간 강제 딜레이 발생
                int result = 0;
                for (int i = 0; i < 5; i++)
                {
                    System.Threading.Thread.Sleep(1000);
                    result++;
                }

                // UI에 결과 반영을 위한 Invoke 처리
                Invoke((MethodInvoker) delegate ()
                {
                    // 해당 UI가 Dispose 되었는지 확인
                    if (IsDisposed) return;

                    label.Text = string.Format("Result : {0}", result);
                });
            });
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday