Q&A

  • Thread 에서 그리기가 안되네요.. ㅜ.ㅜ
기존 그리기 함수를 Thread에서 불러서 사용했는데. 잘 그려지지 않습니다.

Thread에서 그리기 함수 호출은 정상 적으로 되구요. 그려질때도 있느데 한번 안그려지면 계속 안그려지더라구요..

Project Test.Exe raised exeption class EOutOfResources with Message '핸들이 잘못되었습니다.'
Process stopped. Use Step or Run to continue.

그리고 Paint Event를 계속 발생 시키면 이런 에러도 뜨구요. (화면 위에서 Dialog Box를 계속 움직이면..)

Thread에서는 그리기를 할수 없나요?,,,

Thread 소스 입니다.

<!--CodeS-->
unit uDrawThread;

interface

uses
  Windows, Classes, SysUtils, SyncObjs;

type
  TDrawThread = class(TThread)
  private
    { Private declarations }
  public
    procedure CreateEvent;
    constructor Create;
    destructor Destroy; override;
    procedure Execute; override;
  end;

var
    fThread : TDrawThread;
    CS : TRTLCriticalSection;
    entDraw : TEvent;
    bThreadFlag : Boolean = False;
implementation

uses
  uView;

constructor TDrawThread.Create;
begin
  inherited Create(false);
  bThreadFlag := true;
  FreeOnTerminate := True;
  Priority        := tpIdle ;
end;

destructor TDrawThread.Destroy;
begin
  inherited;
  DeleteCriticalSection(CS);
  entDraw.Free;
end;

procedure TDrawThread.CreateEvent;
begin
  InitializeCriticalSection(CS);
  entDraw := TEvent.Create(nil, false, false, 'test');
end;

procedure TDrawThread.Execute;
begin

  while not Terminated do
  begin
     EnterCriticalSection(CS);
     sleep(1);
     if entDraw.WaitFor(INFINITE) = wrSignaled then begin
       fView.DrawDesign; // 그리기 함수 호출
       entDraw.ResetEvent;
     end;
     LeaveCriticalSection(CS);
  end;
end;

end.
<!--CodeE-->

이틀 동아 미치겠네요.. -.-;
좋은답변 부탁드립니다.
그럼.. ~~~
4  COMMENTS
  • Profile
    김동원 2008.01.09 03:43
    Execute함수 중에서 fView라는 instance가 TObject를 상속받은 경우에는
    CriticalSection만으로 해결이 안되구요
    TThread에 정의된 Synchronize함수를 이용해야 합니다.
    다음과 같이 바꾸면 될듯 합니다.

    // 이 procedure를 class정의부(Type)에 추가합니다.
    procedure TDrawThread.DoDraw;
    begin
      fView.DrawDesign; // 그리기 함수 호출
    end;

    procedure TDrawThread.Execute;
    begin
      while not Terminated do
      begin
         if entDraw.WaitFor(INFINITE) = wrSignaled then begin
           Synchronize(DoDraw); // TObject를 상속받은 instance에 뭔가를 수정/실행할때...
           entDraw.ResetEvent;
         end;
      end;
    end;

    도움이 되셨길 바랍니다.


  • Profile
    액숀가면 2008.01.09 22:45
    Synchronize 함수를 사용해서 정상적으로 그리기는 하는데...
    그리는 동안 다른 동작을 할수 없어서말이죠...
    그리는 동안 버튼이나 화면 전환등이 전혀 이루어 지지 않거든요...
    그럼 Thread 사용하는게 무의미하지 않나 싶어서요...

    어떻게 하면 좋죠?.... 흑흑

    좋은 답변 부탁드립니다.
  • Profile
    프리맨 2008.01.09 23:57
    Canvas 핸들은 수시로 바뀌는데 쓰레드가 이전 핸들로 그리게 돼면 그런 에러가 나옵니다.
    fView에서 Canvas에 그리기를 하는 부분 전부 Canvas.Lock ~ Canvas.Unlock으로 감싸세요.
    그리고 그리기 도중 Synchronize가 꼭 필요한 부분이 있다면 분리해서
    Synchronize로 돌려줘야 합니다. 통째로 Synchronize에 넣지 마시고 부분부분
    동기화의 최소단위로 나누고 필요한것만 각각 돌려줘야 쓰레드 효과가 나옵니다.

    그리고 Lock,Unlock, 크리티컬섹션 쓰실때는 try..finally도 꼭 써주셔야 합니다.


  • Profile
    액숀가면 2008.01.10 22:19
    ㅎㅎㅎ
    몇가지 버그는 있지만 답변 처럼하니까 어느정도 구동은 되는거 같군요..
    다시한번 감사드립니다. ^^

    그럼... ^^;
    버그잡으러 가야지 ㅎㅎ