당신은 소유자로 NULL을 통과해야하고 위험 또한 스레드 내부으로 CoInitialize 및 CoUninitialize를 호출 만든 개체를 직접 삭제 스레드 당 한 번, 클라이언트의 수명 동안 OnExecute
이벤트가 여러 번 트리거됩니다. 당신이합니다 (TIdTCPServer::Scheduler
속성에 TIdSchedulerOfThreadPool
구성 요소를 연결하여) TIdTCPServer
풀링 스레드를 사용하지 않는 경우
은, 당신은/초기화하여 ADO 개체를 마무리 한 후 TIdTCPServer::OnExecute
이벤트로에서 사용하는 TIdTCPServer::OnConnect
및 TIdTCPServer::OnDisconnect
이벤트를 사용할 수 있습니다 필요한, 예를 들면 :
class TMyContextData
{
public:
TADOConnection *sql_conn;
TADOQuery *pos_q;
TMyContextData();
~TMyContextData();
};
TMyContextData::TMyContextData()
{
sql_conn = new TADOConnection(NULL);
pos_q = new TADOQuery(NULL);
}
TMyContextData::~TMyContextData()
{
delete pos_q;
delete sql_conn;
}
void __fastcall TMyForm::tcp_serverConnect(TIdContext *AContext)
{
::CoInitialize(NULL);
AContext->Data = new TMyContextData;
}
void __fastcall TMyForm::tcp_serverDisconnect(TIdContext *AContext)
{
delete static_cast<TMyContextData*>(AContext->Data);
AContext->Data = NULL;
::CoUninitialize();
}
void __fastcall TMyForm::tcp_serverExecute(TIdContext *AContext)
{
TMyContextData *pData = static_cast<TMyContextData*>(AContext->Data);
// use pData->sql_conn and pData->pos_q as needed...
}
또는 대신 TIdServerContext
에서 새 클래스를 파생 :
class TMyContext : public TIdServerContext
{
public:
TADOConnection *sql_conn;
TADOQuery *pos_q;
__fastcall TMyContext(TIdTCPConnection *AConnection, TIdYarn *AYarn, TIdContextThreadList *AList = NULL);
__fastcall ~TMyContext();
};
__fastcall TMyContext::TMyContext(TIdTCPConnection *AConnection, TIdYarn *AYarn, TIdContextThreadList *AList)
: TIdServerContext(AConnection, AYarn, AList)
{
::CoInitialize(NULL);
sql_conn = new TADOConnection(NULL);
pos_q = new TADOQuery(NULL);
}
__fastcall TMyContext::~TMyContext()
{
delete pos_q;
delete sql_conn;
::CoUninitialize();
}
__fastcall TMyForm::TMyForm(TComponent *Owner)
: TForm(Owner)
{
// do this before activating TIdTCPServer
tcp_server->ContextClass = __classid(TMyContext);
}
void __fastcall TMyForm::tcp_serverExecute(TIdContext *AContext)
{
TMyContext *pContext = static_cast<TMyContext*>(AContext);
// use pContext->sql_conn and pContext->pos_q as needed...
}
을하지만, 요하는 경우 스레드 풀링을 사용하는 경우 여러 클라이언트가 동일한 실제 스레드에 의해 처리 될 수 있으므로 COM 초기화를 TIdContext
개체를 관리하는 실제 스레드 개체로 옮겨야합니다 (ADO 개체를 다시 스레드로 이동하여 다시 사용할 수 있도록해야 함). 여러 고객의 경우) : 예 :
class TMyADOThread : public TIdThreadWithTask
{
protected:
virtual void __fastcall AfterExecute();
virtual void __fastcall BeforeExecute();
public:
TADOConnection *sql_conn;
TADOQuery *pos_q;
__fastcall TMyADOThread(TIdTask *ATask = NULL, const String AName = "");
};
__fastcall TMyADOThread::TMyADOThread(TIdTask *ATask, const String AName)
: TIdThreadWithTask(ATask, AName)
{
}
void __fastcall TMyADOThread::BeforeExecute()
{
TIdThreadWithTask::BeforeExecute();
::CoInitialize(NULL);
sql_conn = new TADOConnection(NULL);
pos_q = new TADOQuery(NULL);
}
void __fastcall TMyADOThread::AfterExecute()
{
delete pos_q;
delete sql_conn;
::CoUninitialize();
TIdThreadWithTask::AfterExecute();
}
__fastcall TMyForm::TMyForm(TComponent *Owner)
: TForm(Owner)
{
// do this before activating TIdTCPServer
IdSchedulerOfThreadPool1->ThreadClass = __classid(TMyADOThread);
}
void __fastcall TMyForm::tcp_serverExecute(TIdContext *AContext)
{
TMyADOThread *pThread = static_cast<TMyADOThread*>(static_cast<TIdYarnOfThread*>(AContext->Yarn)->Thread);
// use pThread->sql_conn and pThread->pos_q as needed...
}
누수가 있다고 생각되는 이유는 무엇입니까? 프로세스 메모리의 증가가 실제 누설을 나타내는 것은 아닙니다. RTL이 캐시하고 해제 된 메모리를 다시 사용한다는 것을 기억하십시오. 다시 OS로 돌아 가지 않습니다. 메모리 누수가 아닌 메모리 단편화 만 보일 수 있습니다. 아직 설치하지 않은 경우 [FastMM] (http://fastmm.sourrceforge.net) 또는 조각화를 방지하도록 설계된 다른 메모리 관리자를 설치해야합니다. –