Co ciekawe u mnie dzialaja obie wersje ?!
U mnie różnie , co pewnie zależy od stanu wątków , czyli
Synchronize jak napisałeś trzeba .
Odświerzyłem porzucony kod "Wizualnego" komponentu TThread .
Zawiera metodę Synchronize i działa ok , jeśli wywołania
ShowMessage wstawi się w funkcję wołaną przez Synchronize .
Komponent można zainstalować w palecie BCB .
Udostępnia metody :
Resume() , wznawianie
Suspend() , zawieszanie
Synchronize(...) identyczne z TThread::Synchronize .
Udostępnia zdarzenie
OnExecute , działające w nowym wątku .
Po utworzeniu obiekt ( new lub umieszczenie na formularzu ) tworzy nowy wątek reprezentowany przez OnExecute .
Wątek jest w stanie Zawieszenia .
//EDIT kod nie kompletny , brak prawidłowego zwalniania obiektu
ThreadComponent.h:
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
class TThreadComponent ;
class TMyThread :public TThread{
TThreadComponent* tc ;
public:
void __fastcall Synchro(TThreadMethod &Method);
__fastcall TMyThread(bool CreateSuspended,
TThreadComponent* tthc);
__fastcall ~TMyThread();
void __fastcall Execute(void);
};
//---------------------------------------------------------------------------
class PACKAGE TThreadComponent : public TComponent
{
private:
TMyThread* pMyThread ;
TNotifyEvent execute ;
protected:
public:
__fastcall TThreadComponent(TComponent* Owner);
__fastcall ~TThreadComponent();
void __fastcall Suspend(void);
void __fastcall Resume(void);
void __fastcall Execute(void);
void __fastcall Synchronize(TThreadMethod &Method);
__published:
__property TNotifyEvent OnExecute = {read=execute ,write=execute
,default = 0};
};
//---------------------------------------------------------------------------
#endif
ThreadComponent.cpp:
#include <basepch.h>
#pragma hdrstop
#include "ThreadComponent.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TThreadComponent *)
{
new TThreadComponent(NULL);
}
//---------------------------------------------------------------------------
__fastcall TThreadComponent::TThreadComponent(TComponent* Owner)
: TComponent(Owner)
{
pMyThread = new TMyThread(true,this);
// pMyThread->FreeOnTerminate = true ; @ POST 03-02-2008 19:00
}
//---------------------------------------------------------------------------
void __fastcall TThreadComponent::Execute(void)
{
if(execute)
{
execute(this);
}
}
//-----------------------------------------------------
void __fastcall TThreadComponent::Synchronize(TThreadMethod &Method)
{
pMyThread->Synchro(Method);
}
//-----------------------------------------------------------------
void __fastcall TThreadComponent::Suspend(void)
{
pMyThread->Suspend();
}
//-----------------------------------------------------------------
void __fastcall TThreadComponent::Resume(void)
{
pMyThread->Resume() ;
}
//-----------------------------------------------------------------
void __fastcall TMyThread::Synchro(TThreadMethod &Method)
{
Synchronize(Method);
}
//-----------------------------------------------------------------
__fastcall TMyThread::TMyThread(bool CreateSuspended,
TThreadComponent* tthc):TThread(CreateSuspended)
{
tc = tthc ;
}
//-----------------------------------------------------------------
__fastcall TMyThread::~TMyThread()
{
;
}
//------------------------------------------------------------------
__fastcall TThreadComponent::~TThreadComponent()
{
// pMyThread->Terminate(); @ POST 03-02-2008 19:00
}
//---------------------------------------------------------------------------
//---------------- posrednie wywolanie wlasciwosci 'execute' przez
//---------------- obiekt TMyThread zawarty w TThreadComponent
//----------------------------------------------------------------------------
void __fastcall TMyThread::Execute(void)
{
tc->Execute();
}
//---------------------------------------------------------------------------
namespace Threadcomponent
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TThreadComponent)};
RegisterComponents("Samples", classes, 0);
}
}
//---------------------------------------------------------------------------
Pytania :
1.
Tylko mam wątpliwości co do destruktorów .
Klasa główna traktowana jako Komponent to 'ThreadComponent'
zawiera ona obiekt "wątkowy" po TThread (TMyThread) tworzony dynamicznie 'new' i z ustawianym parametrem FreeOnTerminate = true ;.
W destruktorze 'ThreadComponent' wywoływana jest jedynie metoda Terminate() na rzecz obiektu TMyThread , co podobno ma zakończyć watek oraz zwolnić zasoby TMyThread .
Destruktor TMyThread jest pusty .
Czy to jest prawidłowo zrobione jeśli chodzi o bezpieczne usunięcie wątku ?
Czy nie trzeba użyć jakiegoś tam WaitFor a jeśli tak to gdzie ?