| View previous topic :: View next topic |
| Author |
Message |
David Fussell Guest
|
Posted: Thu Jun 24, 2004 10:34 am Post subject: Using event handlers |
|
|
Hi,
I'm using a TThread class. Since this component doesn't appear in object
manager, I can't find a way of hooking into the OnTerminate event trigger.
How can I specify a method I wish to be called on this event?
Thanks
David
|
|
| Back to top |
|
 |
JD Guest
|
Posted: Thu Jun 24, 2004 10:54 am Post subject: Re: Using event handlers |
|
|
"David Fussell" <dfussell_nospam_ (AT) aimltd (DOT) co.uk> wrote:
| Quote: | [...] I can't find a way of hooking into the OnTerminate event
|
Simply assign it in the threads constructor:
//-------------------------------------------------------------
__fastcall TMyThread::TMyThread(bool CreateSuspended) : TThread(CreateSuspended)
{
OnTerminate = DoTerminate;
}
//-------------------------------------------------------------
void __fastcall TMyThread::DoTerminate(TObject *Sender)
{
//
}
//-------------------------------------------------------------
You should not that the code inside the OnTerminate event
executes within the main thread. If you need the code to be
execute within the context of the thread, it should be placed
at the end of it's Execute method:
//-------------------------------------------------------------
void __fastcall TMyThread::Execute()
{
while( !Terminated )
{
// main loop here
}
// OnTerminate here
}
//-------------------------------------------------------------
~ JD
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu Jun 24, 2004 5:30 pm Post subject: Re: Using event handlers |
|
|
"JD" <nospam (AT) nospam (DOT) com> wrote
| Quote: | Simply assign it in the threads constructor:
|
Bad move. For one thing, a thread already has a DoTerminate() method
inherited from TThread. Second, classes should never assign handlers to
their own events. That is the responsibility of code outside the class to
manage instead. You should be doing something more like the following
instead:
void __fastcall TMyForm::DoSomething()
{
//...
TMyThread *thread = new TMyThread;
thread->OnTerminate = ThreadTerminated;
thread->Resume();
//...
}
void __fastcall TMyForm::ThreadTerminate(TObject *Sender)
{
//...
}
__fastcall TMyThread::TMyThread() : TThread(true)
{
}
| Quote: | If you need the code to be execute within the context
of the thread, it should be placed at the end of it's
Execute method:
|
Or in the inherited DoTerminate() method, which is always executed when
Execute() returns.
void __fastcall TMyThread::Execute()
{
while( !Terminated )
{
// main loop here
}
}
void __fastcall TMyThread::DoTerminate()
{
// OnTerminate code here
}
Gambit
|
|
| Back to top |
|
 |
JD Guest
|
Posted: Thu Jun 24, 2004 10:41 pm Post subject: Re: Using event handlers |
|
|
"Remy Lebeau (TeamB)" <gambit47.no.spam (AT) no (DOT) spam.yahoo.com> wrote:
| Quote: |
"JD" <nospam (AT) nospam (DOT) com> wrote in message
news:40dab2d9$1 (AT) newsgroups (DOT) borland.com...
Simply assign it in the threads constructor:
Bad move. [...]
void __fastcall TMyForm::DoSomething()
{
//...
thread->OnTerminate = ThreadTerminated;
//...
}
void __fastcall TMyForm::ThreadTerminate(TObject *Sender)
{
//...
}
|
Got it. I should have known better any way since I already
knew that OnTerminate executes in the main thread.
| Quote: | If you need the code to be executed within the context
of the thread, it should be placed at the end of it's
Execute method:
Or in the inherited DoTerminate() method, which is always
executed when Execute() returns.
|
Ok - now you got me confused. If OnTerminate executes within
the context of the main thread, and DoTerminate calls OnTerminate,
how does it work that Doterminate uses it's thread but OnTerminate
does not?
~ JD
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu Jun 24, 2004 10:58 pm Post subject: Re: Using event handlers |
|
|
"JD" <nospam (AT) nospam (DOT) com> wrote
| Quote: | If OnTerminate executes within the context of the main
thread, and DoTerminate calls OnTerminate, how does
it work that Doterminate uses it's thread but
OnTerminate does not?
|
DoTerminate() is called automatically by TThread immediately after Execute()
returns. Then DoTerminate() uses Synchronize() to trigger the OnTerminate
event handler if one is assigned:
procedure TThread.CallOnTerminate;
begin
if Assigned(FOnTerminate) then FOnTerminate(Self);
end;
procedure TThread.DoTerminate;
begin
if Assigned(FOnTerminate) then Synchronize(CallOnTerminate);
end;
Gambit
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu Jun 24, 2004 11:00 pm Post subject: Re: Using event handlers |
|
|
"Remy Lebeau (TeamB)" <gambit47.no.spam (AT) no (DOT) spam.yahoo.com> wrote
| Quote: | DoTerminate() is called automatically by TThread immediately after
Execute() returns. Then DoTerminate() uses Synchronize() to
trigger the OnTerminate event handler if one is assigned
|
Since Borland had the good insight of making DoTerminate() virtual, it makes
a good place to perform cleanup code inside the thread itself that is always
executed regardless of how Execute() exits (whether normally or via an
uncaught exception).
Gambit
|
|
| Back to top |
|
 |
|