|
먼저 답변을 준 오빠께 감사드려요~
물론 이 경우엔 try __finally가 더 효율적이네요.
제가 워낙 try~ catch를 좋아해서 자주 쓰다보니까 이것만 쓰게 되더라구요. 그리고 Synchronize에
대한 답변 감사함다. 그런 용도로 쓰는 것이었군요. 그리고 Dowork->Suspend()의 경우 제가 헬프에
서 보아서 알고 있었는데 이상하게 여기서 그렇게 하면 폼이 안뜨고 데몬이 뻗어버리는 경우가 생
겨서 안쓴것이었어요. 불쌍한 데몬.... *^0^*
위의 소스문제는 쓰레드에서 디비와 쪽쪽이시 생긴 세션이 어플에서 사용되는 세션과 중복이 되어
데몬이 죽어버리는 문제인 것으로 밝혀냈슴다. 왜냐하면 어플에서는 세션이 로컬앨리어스를 만드
는 데 사용되었습니다.
소스는 다음과 같아요.
// nMail Server의 패스로 메일링 리스트 앨리어스를 생성하는 루틴
void __fastcall TListDemon::CreateLocalAlias()
{
String Alias = UserdbPath;
Alias = ExtractFileDir(UserdbPath) + "\\list\\";
if (!DirectoryExists(ExtractFileDir(Alias)))
{
CreateDirectory(Alias.c_str(), 0);
}
try
{
Session->AddStandardAlias("Neant", Alias, "PARADOX");
Session->SaveConfigFile();
}
catch (...)
{
MessageBox(Handle, "Error Creating Alias", "Error", 0);
return;
}
}
// nMail Server의 패스로 메일링 리스트 앨리어스를 생성하는 루틴
void __fastcall TListDemon::DeleteLocalAlias()
{
try
{
Session->DeleteAlias("Neant");
Session->SaveConfigFile();
}
catch (...)
{
MessageBox(Handle, "Error Deleting Alias", "Error", 0);
return;
}
}
즉 쉽게 말해서 잘은 모르겟지만 ^-_-^;; 어플에서 사용되는 세션과 쓰레드에서 사용되는 세션이
같아서 생긴문제인 것 같아요. 어차피 어플 자체도 하나의 쓰레인것을 감안하면 2개의 쓰레드가 동
일한 세션으로 디비와 쪽쪽이를 해서 생긴것 같습니다. 결론을 내면 "각각의 쓰레드에서 DB와 쪽쪽
이를 할때 세션도 달라야 한다" 라는 것을 알았습니다.
자 그럼 빌더소녀의 수정된 소스임다.
쓰레드 클래스부
class TDowork : public TThread
{
private:
TSession *BackSession;
protected:
void __fastcall DistributeMail();
void __fastcall Execute();
public:
String RootPath; // 메인 폼에서 접근하기위해 Public으로 선언.
__fastcall TDowork(bool CreateSuspended);
};
쓰레드의 구현부
__fastcall TDowork::TDowork(bool CreateSuspended)
: TThread(CreateSuspended)
{
// 종료시 쓰레드 메모리 해제
FreeOnTerminate = true;
// 놀때 일해요.
Priority = tpIdle;
}
//---------------------------------------------------------------------------
void __fastcall TDowork::Execute()
{
// 데몬 쓰레드가 사용할 새로운 BDE 세션을 만든다.
BackSession = new TSession(NULL);
BackSession->SessionName = "Mystic Eyes";
while (!Terminated)
{
DistributeMail();
}
delete BackSession;
}
//---------------------------------------------------------------------------
void __fastcall TDowork::DistributeMail()
{
TQuery *query1, *query2;
try
{
String Domain, List, Member, DomainPath, ListPath, MemberPath;
query1 = new TQuery(NULL);
query2 = new TQuery(NULL);
query1->DatabaseName = "Neant";
query2->DatabaseName = "Neant";
query1->SessionName = BackSession->SessionName;
query2->SessionName = BackSession->SessionName;
query1->Close();
query1->SQL->Clear();
query1->SQL->Add("SELECT DOMAINNAME, LIST FROM LIST");
query1->Open();
while (!query1->Eof)
{
Domain = query1->FieldByName("DOMAINNAME")->AsString;
List = query1->FieldByName("LIST")->AsString;
TSearchRec neant;
DomainPath = RootPath + "\\" + Domain;
ListPath = DomainPath + "\\" + List + "\\" + "mailbox\\";
int found = FindFirst(ListPath + "*.*", faAnyFile, neant);
while (!found)
{
query2->Close();
query2->SQL->Clear();
query2->SQL->Add("SELECT MEMBER FROM MEMBER");
query2->SQL->Add("WHERE DOMAINNAME = '" + Domain + "'");
query2->SQL->Add("AND LIST = '" + List + "'");
query2->Open();
String SrcPath, DesPath;
while (!query2->Eof)
{
Member = query2->FieldByName("MEMBER")->AsString;
MemberPath = DomainPath + "\\" + Member + "\\mailbox\\";
SrcPath = ListPath + neant.Name;
DesPath = MemberPath + neant.Name;
CopyFile(SrcPath.c_str(), DesPath.c_str(), false);
query2->Next();
}
found = FindNext(neant);
DeleteFile(SrcPath.c_str());
}
FindClose(neant);
query1->Next();
}
}
catch (...)
{
delete query1, query2;
return;
}
query1->Close();
query2->Close();
delete query1, query2;
}
과 같이 햇더니 데몬이 안죽고 마구 일을 하는거 있죠... 참 신기해라... *^0^* 암튼 이렇게 해결
하였어여. 참고로 위의 소스는 컴포넌트와 앨리어스 동적생성과 해제, 쿼리사용법, 파일 검색 카
피 삭제등등이 있으니 혹시 첨보는 분야라고 생각되는 언니 오빠들은 참고하세요.
솔직히 아직 모르는 것이 많은 초보로서 많은 고수 오빠 언니들에게 요청함다. 질문이나 답변 하
실 때 해당되는 소스를 공개해 주세요.... ^-_-^ 그래야 그거라도 보고 공부를 할 수가 있슴다.
사실 이 사이트를 알고난 뒤로 한층 실력이 높아졌지만 그러나 아직도 배가 고픈게 넘많아요.
그럼 부탁함다... *^0^*
루루팡 루루피 루루얏~ 즐프! - 나의 사랑 에보니 -
|