Q&A

  • thread에서 synchronize에서 문제가 생깁니다.
아래와 같이 해 보았습니다.



=== 호출폼

unit processing;



interface



uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, ComCtrls, ExtCtrls, ThreadProcess;



const

WM_THREAD_COMPLETE = WM_APP + 5437;



type

Tfrm_processing = class(TForm)

btn_cancel: TButton;

ProgressBar1: TProgressBar;

Animate1: TAnimate;

Label1: TLabel;

procedure btn_cancelClick(Sender: TObject);

procedure FormShow(Sender: TObject);

private

FThread: TPrimeThrd;

procedure HandleThreadCompletion(var Message: TMessage);

{ Private declarations }

public

{ Public declarations }

end;



var

frm_processing: Tfrm_processing;



implementation



{$R *.DFM}



procedure Tfrm_processing.HandleThreadCompletion(var Message: TMessage);

begin

if Assigned(FThread) then

begin

FThread.WaitFor;

FThread.Free;

FThread := nil;

end;

Close;

end;



procedure Tfrm_processing.btn_cancelClick(Sender: TObject);

begin

if Assigned(FThread) then

begin

FThread.Terminate;

FThread.WaitFor;

FThread.Free;

FThread := nil;

end;

end;



procedure Tfrm_processing.FormShow(Sender: TObject);

begin

Screen.Cursor := crAppStart;

if not Assigned(FThread) then

begin

FThread := TPrimeThrd.Create(False);

FThread.FreeOnTerminate := False;

try

with FThread do

begin

IniFileName := CurrFileName;

TempDirectory := TempDir;

Resume;

end;

except

on EConvertError do

begin

FThread.Free;

FThread := nil;

end;

end;

end;

end;



end.





== thread



unit ThreadProcess;



interface



uses

Classes, IniFiles;



type

TPrimeThrd = class(TThread)

Private

FTempDir: String;

FIniFileName: String;

FCaption: String;

protected

procedure UpdateLabel;

function StartFileCopy: Boolean;

procedure Execute; override;

public

property IniFileName: String write FIniFileName;

property TempDirectory: String write FTempDir;

end;



implementation



uses SysUtils, Dialogs, Windows, processing;



procedure TPrimeThrd.UpdateLabel;

begin

frm_processing.Label1.Caption := FCaption;

end;



procedure TPrimeThrd.Execute;

begin

if not Terminated then

begin

if StartFileCopy then

PostMessage(frm_processing.Handle, WM_THREAD_COMPLETE, 0, 0);

end;

end;



function TPrimeThrd.StartFileCopy: Boolean;

begin

.

.

.

FCaption := '시작합니다...';

Synchronize(UpdateLabel);

Result := True;

end;



end.



문제는 위의

procedure TPrimeThrd.UpdateLabel;

begin

frm_processing.Label1.Caption := FCaption;

end;

에서 frm_processing.Label1 을 액세스 할수가 없어서 Access Violation이 발생합니다.

처음 해 보는 거라서 왜 문제가 생기는 지를 알 수가 없네요...



좀 알려 주십시오. 고맙습니다.

2  COMMENTS
  • Profile
    김정 2000.10.14 05:48
    안녕하세요?

    고드름 김정입니다.



    다른 Unit1 과 Unit2 에서 다른 편의 객체를 참조할 경우,

    uses 구문에 해당 unit명만 넣어주면 됩니다.



    하지만 객체 참조의 Circula 방식의 참조는 불가능합니다.

    즉, 서로 Uni1은 Unit2를, 그리고 Unit2는 Unit1을 참조하는게 안됩니다.

    ( 일반 함수 참조는 가능하더군요... )



    이럴 경우 어쩔 수 없지, 한 Unit 내에서 두 개의 객체를 구현해야 합니다.

    그럼.



    김경식 wrote:

    > 아래와 같이 해 보았습니다.

    >

    > === 호출폼

    > unit processing;

    >

    > interface

    >

    > uses

    > Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    > StdCtrls, ComCtrls, ExtCtrls, ThreadProcess;

    >

    > const

    > WM_THREAD_COMPLETE = WM_APP + 5437;

    >

    > type

    > Tfrm_processing = class(TForm)

    > btn_cancel: TButton;

    > ProgressBar1: TProgressBar;

    > Animate1: TAnimate;

    > Label1: TLabel;

    > procedure btn_cancelClick(Sender: TObject);

    > procedure FormShow(Sender: TObject);

    > private

    > FThread: TPrimeThrd;

    > procedure HandleThreadCompletion(var Message: TMessage);

    > { Private declarations }

    > public

    > { Public declarations }

    > end;

    >

    > var

    > frm_processing: Tfrm_processing;

    >

    > implementation

    >

    > {$R *.DFM}

    >

    > procedure Tfrm_processing.HandleThreadCompletion(var Message: TMessage);

    > begin

    > if Assigned(FThread) then

    > begin

    > FThread.WaitFor;

    > FThread.Free;

    > FThread := nil;

    > end;

    > Close;

    > end;

    >

    > procedure Tfrm_processing.btn_cancelClick(Sender: TObject);

    > begin

    > if Assigned(FThread) then

    > begin

    > FThread.Terminate;

    > FThread.WaitFor;

    > FThread.Free;

    > FThread := nil;

    > end;

    > end;

    >

    > procedure Tfrm_processing.FormShow(Sender: TObject);

    > begin

    > Screen.Cursor := crAppStart;

    > if not Assigned(FThread) then

    > begin

    > FThread := TPrimeThrd.Create(False);

    > FThread.FreeOnTerminate := False;

    > try

    > with FThread do

    > begin

    > IniFileName := CurrFileName;

    > TempDirectory := TempDir;

    > Resume;

    > end;

    > except

    > on EConvertError do

    > begin

    > FThread.Free;

    > FThread := nil;

    > end;

    > end;

    > end;

    > end;

    >

    > end.

    >

    >

    > == thread

    >

    > unit ThreadProcess;

    >

    > interface

    >

    > uses

    > Classes, IniFiles;

    >

    > type

    > TPrimeThrd = class(TThread)

    > Private

    > FTempDir: String;

    > FIniFileName: String;

    > FCaption: String;

    > protected

    > procedure UpdateLabel;

    > function StartFileCopy: Boolean;

    > procedure Execute; override;

    > public

    > property IniFileName: String write FIniFileName;

    > property TempDirectory: String write FTempDir;

    > end;

    >

    > implementation

    >

    > uses SysUtils, Dialogs, Windows, processing;

    >

    > procedure TPrimeThrd.UpdateLabel;

    > begin

    > frm_processing.Label1.Caption := FCaption;

    > end;

    >

    > procedure TPrimeThrd.Execute;

    > begin

    > if not Terminated then

    > begin

    > if StartFileCopy then

    > PostMessage(frm_processing.Handle, WM_THREAD_COMPLETE, 0, 0);

    > end;

    > end;

    >

    > function TPrimeThrd.StartFileCopy: Boolean;

    > begin

    > .

    > .

    > .

    > FCaption := '시작합니다...';

    > Synchronize(UpdateLabel);

    > Result := True;

    > end;

    >

    > end.

    >

    > 문제는 위의

    > procedure TPrimeThrd.UpdateLabel;

    > begin

    > frm_processing.Label1.Caption := FCaption;

    > end;

    > 에서 frm_processing.Label1 을 액세스 할수가 없어서 Access Violation이 발생합니다.

    > 처음 해 보는 거라서 왜 문제가 생기는 지를 알 수가 없네요...

    >

    > 좀 알려 주십시오. 고맙습니다.

  • Profile
    김경식 2000.10.14 09:30
    답변 감사드립니다. 많은 도움이 되었습니다. 꾸벅!

    • 신승욱
    • 2000.10.14 00:01
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 최진석
      2000.10.14 01:15
      로컬전용아이피가 있습니다.. 192.168.0 이 있고 192.168.1 뭐 이거 하나면 되겠죠... 신승욱 wrote: ...
    • 신승욱
      2000.10.14 01:24
      최진석 wrote: > 로컬전용아이피가 있습니다.. > 192.168.0 이 있고 > 192.168.1 뭐 이거 하나면 되겠죠...
    • 최진석
      2000.10.15 04:08
      로컬로만 쓰는 거기때문에 특별히 주의 할건 없는것 같습니다.. 신승욱 wrote: > 최진석 wrote: > > ...
    • 김경식
    • 2000.10.13 23:58
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 김정
      2000.10.14 05:48
      안녕하세요? 고드름 김정입니다. 다른 Unit1 과 Unit2 에서 다른 편의 객체를 참조할 경우, uses 구문...
    • 김경식
      2000.10.14 09:30
      답변 감사드립니다. 많은 도움이 되었습니다. 꾸벅!
    • 왕초보
    • 2000.10.13 23:55
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 김정
      2000.10.14 05:45
      안녕하세요? 고드름 김정입니다. 저 아래에도 비슷한 질문이 있던데, Struct는 Record로 구현합니다. ...
    • 김정
      2000.10.14 05:42
      안녕하세요? 고드름 김정입니다. 이미지 thumbnail view를 만드시려는 것 같군요. TListBox 의 OwnerD...
    • 프지초보
      2000.10.18 01:50
      답변에 감사 드립니다. 고민해서 많이 해 봤는데.. 강좌에 있군요.. 아 서글퍼라.. 고수님께서 아주 쉽고 ...
    • 정하
    • 2000.10.13 23:33
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 강호규
      2000.10.14 01:40
      델파이초보 wrote: > index를 사용하면 오직 read 밖에 안되는데.. > table을 수정및 삭제 할려면 어떻...
    • 이광형
      2000.10.13 22:57
      안녕하세요... 도움이 될지 모르겠지만... 쿼리발행을 이렇게 한번 해보시지요... 출력은 쿼리 발행후 맞...
    • metald.
    • 2000.10.13 21:22
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 어린왕자
      2000.10.14 21:29
      metald. wrote: > > Unit1에서 uses Unit2 하고 Unit2에 있는 메소드를 호출하면 > 클래스 메소드를 ...
    • 김현
      2000.10.13 23:41
      꼭 클래스 메소드를 쓸 필요는 없는데요...대충 보니까..unit2 에 있는 클래스의 오브젝트를 만들지 않고 ...
    • 임형호
      2000.10.14 02:43
      인덱스 생성에 관한거라면... DB마다 조금씩 다르니까...책을 참고하셔야할거구요. table 사용시에는 ind...
    • 한승구
    • 2000.10.13 21:03
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 김정
      2000.10.14 05:38
      안녕하세요? 고드름 김정입니다. 델파이에는 TTimer 라는 객체가 있습니다. TTimer의 인스턴스에 Inte...
    • 한승구
      2000.10.16 19:09
      김정 wrote: > 안녕하세요? > 고드름 김정입니다. > > 델파이에는 TTimer 라는 객체가 있습니다. > T...
    • 김정
      2000.10.16 19:55
      안녕하세요? 고드름 김정입니다. 질문하신 TTimer 예제입니다. Inspecter에서 Timer1의 Enabled은 Fal...
    • 한승구
      2000.10.17 18:28
      김정 wrote: > 안녕하세요? > 고드름 김정입니다. > > 질문하신 TTimer 예제입니다. > Inspecter에서...
    • delpo
    • 2000.10.13 20:58
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 김현
      2000.10.13 23:48
      프라퍼티 이름과 여러가지 정황으로 미루어 보아 Listen.Checked 프라퍼티의 type은 Boolean형입니다. 그러...
    • 최석기
      2000.10.13 21:52
      기존에 CheckBox에 Check된 상태를 반대로 바꾼다는 의미죠.. 이 프로시져를 들어오기전에 CheckBox.Check...
    • 임준
    • 2000.10.13 20:51
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 김정
      2000.10.14 05:36
      안녕하세요? 고드름 김정입니다. TMetafile 인스턴스를 생성하고, 객체 내의 Canvas에 image을 덮어 D...
    • coolling
    • 2000.10.13 20:47
    • 3 COMMENTS
    • /
    • 0 LIKES
    • coolling
      2000.10.16 18:56
      coolling wrote:
    • 성더기
      2000.10.14 21:03
      coolling wrote: > 쿼리를 했습니다. > 쿼리한 결과의 record수가 필요하더군요.. > 다시 sql을 사용해...
    • 태여니
      2000.10.13 22:22
      저도 Recordcount를 써본 경험이 있어서 경험을 토대로 말씀드립니다. 한마디로 Recordcount는 병신 입...
    • Cha
    • 2000.10.13 20:39
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 구창민
      2000.10.13 20:56
      Cha wrote: > Tfontstyle을 String타입으루 보여주고 싶어염... 어케 해야 하나염... > 꼬옥 답해 주세염...
    • 초생
    • 2000.10.13 20:30
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 강인규
      2000.10.14 05:38
      제가 썼던 소스로 설명을 드리겠습니다. 날릴 데이터와 받을 데이터는 모두 메모리 스트림으로 만드시공...
    • 김정
      2000.10.14 05:34
      안녕하세요? 고드름 김정입니다. 네.. 마찬가지 방법입니다. icsdelphiinternet 밑에 HTTPTST.DPR 프...
    • 김현
      2000.10.13 23:44
      struct 랑 같다고 볼 수 있는게 델파이에는 record라고 잇습니다. union 은 가변 레코드를 쓰시면 되죠....
    • 남기석
      2000.10.14 10:33
      안녕하세요 청개구리 남기석입니다. 정말 델파이와 상관 없는 질문이네요... Windows 폴더에 보면.....