장성호님과 여러분이 아래아래에 있는 제 팁 속의 질문에 대한
정답을 말하라고 해서 그것에 대한 답변으로 올립니다.
제 질문의 핵심은 쓰레드를 이동한 동시 실행 기법인데,
사실 머.. 신선한 주제는 아닙니다만, 의외로 실전에서 답답하게 코딩된 경우를 많이 봅니다.
함수가 실행되는 동안 화면이 꼼짝하지 않는 상황을 벗어날때
그외 다중으로 루틴을 실행할때 필요한 기법입니다.
이 클래스는 실전에 상당한 가치가 있으리라 생각됩니다.
//---------------------------------------------------------------------------
화면에 버턴을 올려 놓고 더블클릭해서 코딩을 합니다.
그런데, 이벤트 함수내에서 무엇을 처리하는 시간이 깁니다.
그러면 화면은 꼼짝을 안하죠... 뭘 클릭해도 가만히 있고...
이렇게 시간이 걸리는 루틴은 쓰레드로 만드는 것이 정석입니다.
하지만 이렇게 쓰레드로 만들고 있자니 좀 번거러운 면이 있습니다.
이것을 일반화 시킬 수는 없을까?
그래서 만든 것이 아래 클래스입니다.
시간이 오래 걸리는 함수를 이 클래스를 생성할때 지정하면
그 함수를 쓰레드에서 실행하고 즉시 리턴됩니다.
그러면 바로 또 다른 화면 조작을 할수 있습니다.
그 함수의 실행이 종료되면 자동으로 쓰레드도 종료됩니다.
아래는 소스입니다.
아주 간단하죠...
일단 TNotifyEvent 형 함수만 지정할 수 있게 했는데,
다른 형의 함수는 소스를 살짝꿍 수정하면 될 것입니다.
//---------------------------------------------------------------------------
// 지정 함수를 쓰레드에서 실행시키는 클래스
// Sender는 호출자 구분이 필요할시 쓰기 위함.
//
//
// Written by 김태성
class TRunThread : public TThread
{
private:
TNotifyEvent OnEvent;
TObject* Sender;
public:
__fastcall TRunThread(TNotifyEvent event, TObject* sender)
: TThread(false)
{
FreeOnTerminate = true;
OnEvent = event;
Sender = sender;
}
void __fastcall Execute()
{
OnEvent(Sender);
}
};
//---------------------------------------------------------------------------
// 요건 쓰레드에 실어서 실행할 함수 입니다.
void __fastcall TForm1::TestFunc(TObject *Sender)
{
// 엄청 시간이 걸리는 루틴.
int k;
for(int c = 0; c < 199999999; c++)
{
k = c;
k++;
c = k;
c--;
}
Caption = k;
Button3->Enabled = true;
}
//---------------------------------------------------------------------------
// 쓰레드를 생성한후 쓰레드에서 함수를 실행한후 즉시 리턴해 프로그램 실행을 계속한다.
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Button3->Enabled = false;
TRunThread* thread = new TRunThread(&TestFunc, Sender);
thread;
}
//---------------------------------------------------------------------------
다음은 사용하기 좀 더 간편하게 스택에 생성할 수 있는 클래스 버전입니다.
//---------------------------------------------------------------------------
// 지정 함수를 쓰레드에서 실행시키는 클래스 (스택생성 가능 버전)
// Sender는 호출자 구분이 필요할시 쓰기 위함.
//
//
// Written by 김태성
class CRunThread
{
class TRunThread : public TThread
{
private:
TNotifyEvent OnEvent;
TObject* Sender;
public:
__fastcall TRunThread(TNotifyEvent event, TObject* sender)
: TThread(false)
{
FreeOnTerminate = true;
OnEvent = event;
Sender = sender;
}
void __fastcall Execute()
{
OnEvent(Sender);
}
};
public:
CRunThread(TNotifyEvent event, TObject* sender)
{
TRunThread* thread = new TRunThread(event, sender);
}
};
//---------------------------------------------------------------------------
// 요건 쓰레드에 실어서 실행할 함수 입니다.
void __fastcall TForm1::TestFunc(TObject *Sender)
{
// 엄청 시간이 걸리는 루틴.
int k;
for(int c = 0; c < 199999999; c++)
{
k = c;
k++;
c = k;
c--;
}
Caption = k;
Button1->Enabled = true;
}
//---------------------------------------------------------------------------
// 쓰레드를 생성한후 쓰레드에서 함수를 실행한후 즉시 리턴해 프로그램 실행을 계속한다.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Button1->Enabled = false;
CRunThread thread(&TestFunc, Sender);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Caption = "하하하";
}
//---------------------------------------------------------------------------
끝.
|
TestFunc
함수가 더 시간이 걸리게 조금 손보시기 바랍니다.