본문 바로가기
Delphi/클래스

익명함수+스레드를 활용한 간단한 스레드 사용 방법

by MonoSoft 2022. 1. 24.
728x90
반응형

익명함수 스레드를 활용한 간단한 스레드 사용 방법

 

기존에는 TThread를 상속하여 구현하였기에 초보시절엔 접근도 어렵고 

잠깐 쓰레드가 필요한 시점에서의 활용도 번거로웠습니다.

 

다행히 델파이 2010버전부터 익명함수가 제공되었는데

덕분에 쓰레드를 아주 손쉽게 사용할 수 있습니다.

 

다만, 여기서는 자세히 설명할 순 없지만

안전한 쓰레드 사용을 위해 크기 2가지를 지켜야 합니다.

1) 쓰레드의 begin ~ end 블록 사이에서

   UI를 조작(변경, 수정, 삭제등)할때는 Syncronize를 이용한다.

 

2) 다른 쓰레드와 동시에 같은 자원(변수, 클래스등)을

공유(동시에 읽거나 쓰는 행위, 포인터를 참조하는 행위)하지 않는다.

 

간단한 예제입니다.

 

1. 100ms 타이머 만들기

델파이 기본 타이머는 윈도우 이벤트 방식으로 구현되므로

 

다음과 같은 치명적인 단점이 있습니다.

1) 정확도가 떨어지고(윈도우 컨디션에 따라 100~500ms 이하 작동 불규칙)

2) 메인UI(메인쓰레드)가 멈추지 않고 작업 불가능

 

그래서 필수로 쓰레드를 이용한 타이머를 사용하게 됩니다.

익명함수를 사용하면 아래와 같이 손쉽게 만들 수 있습니다.

 

procedure TForm1.FormCreate(Sender: TObject);

begin

    TThread.CreateAnonymousThread(procedure

    begin

      while Applicaton.Terminated do

      begin

        Sleep(100);

        DoTimerTick; // DoTimerTick에서 소요되는 시간을 모두 기다리므로 while문을 통해 중복 실행되지는 않습니다.

      end;

    end).Start;

end;

 

procedure TForm1.DoTimerTick1;

var

  i, k: integer;

begin

  // 여기서부터 백그라운드 작업을 하면 됩니다.

  // 메인 UI를 멈추게 하지 않습니다.

  // 이런 for 구문도 아주 빠르게 동작하며 메인UI도 정상적으로 작동합니다.

  for i ;= 0 to 9999999999 do

  begin

    Inc(k);

  end;

 

  // sleep도 메인UI가 정상적으로 작동합니다.

  sleep(1000);

  // 메인 UI를 조작하려면 Synchronize 처리합니다.

  TThread.Synchronize (TThread.CurrentThread, procedure ()

  begin

    Label1.Caption := IntToStr(k);

  end);

 

  ShowLogMsg('타이머 작동 중...');

end;

 

procedure TForm1.ShowLogMsg(AMsg: String);

begin

  // 최초 호출 시점이 쓰레드라면 아래와 같이 Synchronize 처리

  TThread.Synchronize (TThread.CurrentThread, procedure ()

  begin  

    Memo1.Lines.Add(AMsg);

  end);

end;

 

2. 버튼 클릭 시 대기시간 구현

procedure TForm1.Button1Click(Sender: TObject);

begin

  Label1.Caption := '파일 복사 시작';

  TThread.CreateAnonymousThread(procedure

  begin

    FileCopy('c:\org.avi', 'd:\dst.avi'); // 용량 100mb avi 파일 복사 

    TThread.Synchronize (TThread.CurrentThread, procedure ()

    begin  

      Label1.Caption := '파일 복사 종료';

    end);

  end).Start;

end;

 

procedure TForm1.Button2Click(Sender: TObject);

begin

  TThread.CreateAnonymousThread(procedure

  begin

    TThread.Synchronize (TThread.CurrentThread, procedure ()

    begin  

      Edit1.ReadOnly := true;

      Edit1.Caption := '2초 후 입력 가능';

    end);

 

    Sleep(2000);

 

    TThread.Synchronize (TThread.CurrentThread, procedure ()

    begin  

      Edit1.ReadOnly := false;

      Edit1.Caption := '이제부터 입력 가능';

    end);    

  end).Start;

end;

728x90
반응형

'Delphi > 클래스' 카테고리의 다른 글

클래스란?  (0) 2023.06.05
쓰레드 추가설명  (0) 2022.03.23
멀티스레드 GUI 동기화  (0) 2022.01.14
델파이 쓰레드(Thread)의 기초  (0) 2021.08.07
델파이 레코드 클래스 성능 비교  (0) 2021.08.05

댓글