출처: http://www.delmadang.com/community/bbs_view.asp?bbsNo=3&bbsCat=0&indx=454853&page=1
기존에는 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;
'언어 > delphi' 카테고리의 다른 글
입력값 검사루틴 - 코드 리팩토링 (0) | 2018.05.15 |
---|---|
초를 0시간 0분 0초식으로 리턴 (0) | 2018.05.15 |
TFrame의 생성 및 해제를 편하게 해주는 TFrame 관리 클래스입니다.. (0) | 2018.04.27 |
복수의 유닛 참조와 간접 유닛 참조 #4 (0) | 2018.04.27 |
유닛 참조와 uses 절 #3 (0) | 2018.04.27 |