線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3051
推到 Plurk!
推到 Facebook!
[<<] [1] [2] [>>]

Thread 求助

缺席
KFC
一般會員


發表:43
回覆:73
積分:23
註冊:2003-03-27

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-22 04:29:10 IP:210.77.xxx.xxx 未訂閱
我在一个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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-23 03:04:03 IP:210.77.xxx.xxx 未訂閱
版主,请帮忙看看。我想很久了,都找不到方法。绪是否无法调用DLL中的方法?
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-23 09:30:41 IP:147.8.xxx.xxx 未訂閱
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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-04-23 13:23:08 IP:210.77.xxx.xxx 未訂閱
还是不行。我将程序改为 procedure TTestThread.execute; begin FreeOnTerminate := True; while not Terminated do begin s := getSomething(xxx); end; messagebox(0, 'Hello', '', MB_OK); end; 我发现信息无法显示出来
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-04-23 14:23:04 IP:147.8.xxx.xxx 未訂閱
引言:还是不行。我将程序改为 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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-24 18:20:58 IP:210.77.xxx.xxx 未訂閱
那句是用来判断s是否某些特定的字符串,如果是则终止绪。不过我已经将那句去了,还是不行。问题一定出在s := getSomething(xxx);上。当我去掉这一句,一切正常。而getSomething(xxx);是另一个类的函数,主要功能是从文件中读取一个大字符串然后返回一个特定的串。
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-04-25 08:51:36 IP:147.8.xxx.xxx 未訂閱
引言:那句是用来判断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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-04-25 09:33:28 IP:210.77.xxx.xxx 未訂閱
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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-04-25 10:17:11 IP:147.8.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-04-25 17:02:52 IP:210.77.xxx.xxx 未訂閱
也不行。没有任何的exception
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-04-25 17:35:14 IP:147.8.xxx.xxx 未訂閱
引言:也不行。没有任何的exception
So 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

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-04-25 18:17:56 IP:210.77.xxx.xxx 未訂閱
哈真奇怪,这样就可以了。但为什么我先前试的就不行?由於我写的是个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

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-04-25 18:45:19 IP:210.77.xxx.xxx 未訂閱
又发现问题。如果在调用Thread时加入这些代码 try TestThread := TTestThread.Create(False); finally TestThread.Destroy; end; 则上例中给出的'Begin' 'Running' 和 ‘End'都不见了,完全没有输出也没有Exception。如果不加这个try..finally,则当该绪完成结束后。下次再生成另一个TestThread时,系统报错:Read Address ... Error
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-04-26 10:11:17 IP:210.3.xxx.xxx 未訂閱
引言: 又发现问题。如果在调用Thread时加入这些代码 try TestThread := TTestThread.Create(False); finally TestThread.Destroy; end; 则上例中给出的'Begin' 'Running' 和 ‘End'都不见了,完全没有输出也没有Exception。如果不加这个try..finally,则当该绪完成结束后。下次再生成另一个TestThread时,系统报错:Read Address ... Error
The 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

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-04-26 13:42:47 IP:210.77.xxx.xxx 未訂閱
谢谢版主,我想再问一下 TestThread.Terminated; 好像没有这个property??? 另外,我看到TThread里有个OnTerminate,是否可以利用来通知绪终止?如果绪不正常地终止,这个事件是否仍会触发?
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-04-27 11:35:28 IP:210.3.xxx.xxx 未訂閱
Terminated is a property of TThread. OnTerminate will not be called for abnormal termination (e.g. force to kill the thread) and in your case you could use it to send a message to the main thread for notification.
KFC
一般會員


發表:43
回覆:73
積分:23
註冊:2003-03-27

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-04-27 12:04:55 IP:210.77.xxx.xxx 未訂閱
谢谢。但我真的找不到terminated这个property。编译时总说没有这属性
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-04-27 16:26:24 IP:210.3.xxx.xxx 未訂閱
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

發送簡訊給我
#19 引用回覆 回覆 發表時間:2003-05-01 03:28:20 IP:210.77.xxx.xxx 未訂閱
但我看到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

發送簡訊給我
#20 引用回覆 回覆 發表時間:2003-05-01 18:15:43 IP:210.0.xxx.xxx 未訂閱
You could redefine it as public as needed. For the TTestTerminate, have you ever try to terminate it, or it keeps running in a loop in the Execute method?
KFC
一般會員


發表:43
回覆:73
積分:23
註冊:2003-03-27

發送簡訊給我
#21 引用回覆 回覆 發表時間:2003-05-01 18:37:08 IP:210.77.xxx.xxx 未訂閱
procedure 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; 就这样。应该有终止吧
sryang
尊榮會員


發表:39
回覆:762
積分:920
註冊:2002-06-27

發送簡訊給我
#22 引用回覆 回覆 發表時間:2003-05-02 11:16:52 IP:202.3.xxx.xxx 未訂閱
引言: 另外我想问,我们某个函数中生成上述的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

發送簡訊給我
#23 引用回覆 回覆 發表時間:2003-05-02 11:40:27 IP:147.8.xxx.xxx 未訂閱
引言:
procedure 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; 
就这样。应该有终止吧
If s equals 0 some time... for testing, how about
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

發送簡訊給我
#24 引用回覆 回覆 發表時間:2003-05-02 12:07:08 IP:210.77.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#25 引用回覆 回覆 發表時間:2003-05-02 12:17:31 IP:147.8.xxx.xxx 未訂閱
引言:还是不行。真的够头痛。另外,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

發送簡訊給我
#26 引用回覆 回覆 發表時間:2003-05-02 15:33:51 IP:210.77.xxx.xxx 未訂閱
OnTerminate只有 Messagebox(0, 'terminated', '', MB_OK);
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#27 引用回覆 回覆 發表時間:2003-05-05 23:12:55 IP:210.0.xxx.xxx 未訂閱
引言:OnTerminate只有 Messagebox(0, 'terminated', '', MB_OK);
這樣就奇怪了,方便把 thread dll 上載嗎?
KFC
一般會員


發表:43
回覆:73
積分:23
註冊:2003-03-27

發送簡訊給我
#28 引用回覆 回覆 發表時間:2003-05-06 00:27:38 IP:210.77.xxx.xxx 未訂閱
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

發送簡訊給我
#29 引用回覆 回覆 發表時間:2003-05-06 09:11:19 IP:147.8.xxx.xxx 未訂閱
引言: function MyDLL_OnStart : Integer; stdcall; var wait :TTestThread; begin wait := TTestThread.create(True); // TestObj.doSomething 是一个事件函数,当Thread终止时触发 wait.OnTerminate := TestObj.doSomething; wait.Resume; Result := 0; end;
KFC
一般會員


發表:43
回覆:73
積分:23
註冊:2003-03-27

發送簡訊給我
#30 引用回覆 回覆 發表時間:2003-05-07 15:09:08 IP:210.77.xxx.xxx 未訂閱
William, 改成Resume后仍是不行。但很奇怪,我将程序的terminate改成DoTerminate后就OK了。请问两者有何区别?
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#31 引用回覆 回覆 發表時間:2003-05-07 15:21:56 IP:147.8.xxx.xxx 未訂閱
引言: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] [>>]
系統時間:2024-05-15 10:56:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!