Thread 求助 |
缺席
|
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
我在一个DLL中写了一个简单的Thread来等待一个条件成立。 procedure TTestThread.execute;
begin
FreeOnTerminate := True;
while True do
begin
s := getSomething(xxx);
if (s is something) then break;
end;
end; 这里,getSomething是一个属於其他类的CALLBack函数,xxx是传递的参数。它每次调用都会返回一个条件。
我想以这个条件来作为退出循环的依据。但是,我发现如果加入了getSomething这个函数以后,循环会立即退出并结束thread。我也试过去掉这个函数并加入
Sleep(),情况还是一样。请问在一个Thread中是否不可以调用其它函数?我要怎样才能实现这个功能? 谢谢 發表人 - KFC 於 2003/04/22 06:04:23
|
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
procedure TTestThread.execute; begin FreeOnTerminate := True; while not Terminated do begin s := getSomething(xxx); // remove this if (s is something) then break; end; end;Try it... if the thread still terminate, there is unhandled exception occured in getSomething... |
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言:还是不行。我将程序改为 procedure TTestThread.execute; begin FreeOnTerminate := True; while not Terminated do begin s := getSomething(xxx); end; messagebox(0, 'Hello', '', MB_OK); end; 我发现信息无法显示出来Because your thread is running in the while loop. Then I think an exception occured in the line if (s is something) then break; ? What exactly is the if statement? |
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言:那句是用来判断s是否某些特定的字符串,如果是则终止绪。不过我已经将那句去了,还是不行。问题一定出在s := getSomething(xxx);上。当我去掉这一句,一切正常。而getSomething(xxx);是另一个类的函数,主要功能是从文件中读取一个大字符串然后返回一个特定的串。First ensure the thread is not suspended nor terminated and any details about the function getSomething? |
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
procedure TTestThread.execute;
begin
FreeOnTerminate := True;
while not Terminated do
begin
s := getSomething(xxx);
end;
messagebox(0, 'Hello', '', MB_OK);
end;
绪一定是被终止了,因为messagebox(0, 'Hello', '', MB_OK);无法到达。而getSomething(xxx)里有一段读取文件的程序。即使去掉getSomething,换成sleep(1000),问题依旧
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言: procedure TTestThread.execute; begin FreeOnTerminate := True; while not Terminated do begin s := getSomething(xxx); end; messagebox(0, 'Hello', '', MB_OK); end; 绪一定是被终止了,因为messagebox(0, 'Hello', '', MB_OK);无法到达。而getSomething(xxx)里有一段读取文件的程序。即使去掉getSomething,换成sleep(1000),问题依旧I don't think so. Refer to the above codes, the message box will not appear when 1) the thread is suspended, 2) the thread is running and not terminated (the while loop) 3) the thread is killed (using API) 4) an exception occured How about this? procedure TTestThread.execute; begin FreeOnTerminate := True; while not Terminated do begin try s := getSomething(xxx); except on E:Exception do begin ShowMessage(E.Message); Terminate; end; end; end; messagebox(0, 'Hello', '', MB_OK); end; {...} TestThread := TTestThread.Create(False); // False.. no need to suspend |
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言:也不行。没有任何的exceptionSo no message box? The thread is running non-stop? So what do you mean by "循环会立即退出并结束thread" in your first post? Perhaps you could add more message box for debug... procedure TTestThread.execute; var HH,MM,SS,MS: word; begin FreeOnTerminate := True; ShowMessage('Begin'); while not Terminated do begin try s := getSomething(xxx); DecodeTime(Now,HH,MM,SS,MS); if SS=0 then ShowMessage('Running'); except on E:Exception do begin ShowMessage(E.Message); Terminate; end; end; end; ShowMessage('End'); end;BTW, it may help if you could post the codes for getSomething.... |
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
哈真奇怪,这样就可以了。但为什么我先前试的就不行?由於我写的是个DLL,getSomething(真正的函数是GetData(para))是DLL接口提供的函数。它做了什么我都不知道,只知道它从一个文本文件中读入一个很大的字符串。 另外我想问,我们某个函数中生成上述的Thread并执行。请问怎样使主函数才能等到Thread完成或结束后再继续以后的操作?
即,
procedure TestThread;
var
TestThread TTestThread;
begin
TestThread := TTestThread.Create(False);
(* How can I wait till TestThread is finish before the followin code is run *)
...
...
end;
|
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言: 又发现问题。如果在调用Thread时加入这些代码 try TestThread := TTestThread.Create(False); finally TestThread.Destroy; end; 则上例中给出的'Begin' 'Running' 和 ‘End'都不见了,完全没有输出也没有Exception。如果不加这个try..finally,则当该绪完成结束后。下次再生成另一个TestThread时,系统报错:Read Address ... ErrorThe example above will kill the thread immediately after it is created. Hence no message box. Try this: try TestThread := TTestThread.Create(False); repeat Application.ProcessMessages; until TestThread.Terminated; finally TestThread.Destroy; end; procedure TTestThread.execute; begin FreeOnTerminate := True; while not Terminated do begin s := getSomething(xxx); if (s is something) then Terminate; sleep(100); end; end;However I think it is better to send a custom message in the thread to notify the main form instead of polling in the main form. |
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
Are you using TThread? From Delphi help: Terminated property (TThread) Indicates whether the thread has been asked to terminate. Delphi syntax: property Terminated: Boolean; C syntax: __property bool Terminated = {read=FTerminated, nodefault}; Description The thread's Execute method and any methods that Execute calls should check Terminated periodically and exit when it's true. The Terminate method sets the Terminated property to true. The Terminate method is the polite way to abort the execution of a thread, but it requires cooperation from the thread’s Execute code. In Windows, using Terminate is recommended over the TerminateThread Win32 API call.
|
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
但我看到Delphi的原代码中,Terminated是一个protected类型的property。所以还是不能直接从外部访问。 另外,我写了一个很简单的class
type
TTestTerminate = class(TObject)
procedure test(Sender :Tobject);
end; var
TestTerminate :TTestTerminate; ...
TestThread = TThread(True);
TestThread.OnTerminate := TestTerminate.test;
TestThread.Execute;
...
但我发现TestTerminate.test始终没有被调用。这是什么回事?
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
sryang
尊榮會員 發表:39 回覆:762 積分:920 註冊:2002-06-27 發送簡訊給我 |
引言: 另外我想问,我们某个函数中生成上述的Thread并执行。请问怎样使主函数才能等到Thread完成或结束后再继续以后的操作? 即, procedure TestThread; var TestThread TTestThread; begin TestThread := TTestThread.Create(False); (* How can I wait till TestThread is finish before the followin code is run *) ... ... end;用 TestThread.WaitFor; 加油喔,喵~
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/ |
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言:If s equals 0 some time... for testing, how aboutprocedure TTestThread.execute; begin FreeOnTerminate := True; while not Terminated do begin try s := getSomething(xxx); if s=0 then terminate; except on E:Exception do begin ShowMessage(E.Message); Terminate; end; end; end;就这样。应该有终止吧 procedure TTestThread.execute; begin FreeOnTerminate := True; while not Terminated do begin try s := getSomething(xxx); if s=0 then terminate; sleep(5000); // test OnTermiante Terminate; except on E:Exception do begin ShowMessage(E.Message); Terminate; end; end; end; |
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
引言: procedure TTestThread.execute; begin FreeOnTerminate := True; while not Terminated do begin try s := getSomething(xxx); if s=0 then terminate; sleep(5000); // test OnTermiante Terminate; except on E:Exception do begin ShowMessage(E.Message); Terminate; end; end; end;还是不行。真的够头痛。另外,getSomething是另一个接口类的method,怎样利用WaitFOR? |
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言:还是不行。真的够头痛。另外,getSomething是另一个接口类的method,怎样利用WaitFOR?WaitFor is for external unit waiting for the termination of the thread, e.g. TestThread.WaitFor; Beware, WaitFor will wait until the thread is termianted... i.e. wait forever if the thread is not terminated. BTW, what is your OnTerminate? |
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
procedure TestObj.doSomething;
begin
Messagebox(0, 'Terminated', '', MB_OK);
end; 这是DLL入口。DLL启动时会自动调用该函数
function MyDLL_OnStart : Integer; stdcall;
var
wait :TTestThread;
begin
wait := TTestThread.create(True);
// TestObj.doSomething 是一个事件函数,当Thread终止时触发
wait.OnTerminate := TestObj.doSomething;
wait.Execute;
Result := 0;
end; 以下是TTestThread中的Execute部分
procedure TWaitThread.Execute;
var
s:Integer;
begin
FreeOnTerminate := True;
try
while not Terminated do
begin
Sleep(100);
s := getSomething();
if s=0 then
Terminate;
end;
except
on E:Exception do
begin
MessageBox(0,PChar('Err ' E.Message), '', MB_OK);
Terminate;
end;
end;
end;
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
KFC
一般會員 發表:43 回覆:73 積分:23 註冊:2003-03-27 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
引言:William, 改成Resume后仍是不行。但很奇怪,我将程序的terminate改成DoTerminate后就OK了。请问两者有何区别?You create the thread as suspended and hence your thread never run and so it never terminate. Resume is used to wake up the thread. Perhaps you can try to show a message box at the end of the Execute method of your thread and test. From Delphi help: DoTerminate method (TThread) Generates an OnTerminate event. Delphi syntax: procedure DoTerminate; virtual; C syntax: virtual void __fastcall DoTerminate(void); Description DoTerminate calls the OnTerminate event handler, but does not terminate the thread. |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |