감사합니다.
한가지만 더..
프로그램을 종료하면서 이런저런 Resource의 Release를 하면서,
Socket /Serial Port들에 대한 Close 로그도 함께 저장하고 싶은데요..
FormCloseQuery이벤트에서
Socket / Serial Port를 Close하면 onDisconnect/onClose Event가 발생하고, 여기서 다시
Log를 쓰게 되는데..
이미 Main Thread와 Log Thread는 Close 이벤트를 지나면서
종료가 되어서, 이 로그를 저장할 수 없는 상황인데요..
그래서, 이 이벤트 (Socket Close/Serial Port의 Close 이벤트)에 대한 로그를 모두 처리할 때까지
Log 스레드와 프로그램의 종료를 지연하고 싶은데..
그냥 Sleep()으로 기다리는 것은 방법이 안되더군요..
어떤 방법이 있을 지?
장성호 님이 쓰신 글 :
: 파일에 기록을 먼저 하고..
: 화면에 표시는 메인폼이 있을때만 하면 되지 않나요?
:
: 대충 다음과 같이..
:
: //---------------------------------------------------------------------------
: void TLogThread::LogWrite(STLogMessage *pLogMessage)
: {
:
: //1) 파일기록을 먼저 하고..
: TDateTime t = pLogMessage->LogTime;
: USHORT iHour, iMinute, iSec, iMSec;
:
: t.DecodeTime(&iHour, &iMinute, &iSec, &iMSec);
:
: UnicodeString sLogMsg;
: sLogMsg = sLogMsg.sprintf(L"[%02d:%02d:%02d] ",iHour, iMinute, iSec);
: sLogMsg += pLogMessage->LogMessage;
:
: if ( pLogMessage->bFile ) {
: m_Log.LogMessage(sLogMsg); // 로그 파일에 기록
: }
:
: //2) 어플이 실행중인 동안 화면에 표시 ...
: if( Application->Terminated==false)
: {
: if ( FormMain->Memo->Lines->Count > 100 ) FormMain->Memo->Lines->Clear();
: FormMain->Memo->Lines->Insert(0, sLogMsg); // 메인 폼의 로그창에 기록
: }
: }
:
:
:
: 그럼..
:
: 땅주인 님이 쓰신 글 :
: : 환경: C++ Builder XE5
: :
: : 화면과 파일에 Log을 기록하는 LogThread를 운영중입니다.
: : 잘 동작하는데, 프로그램 종료할 때 문제가 생기네요.
: :
: : 로그를 기록하는 것이 스레드로 빠져있으니
: : 로그를 써야할 상황인데, MainForm이 먼저 종료되면서
: : 로그가 기록되지 않는 증상이 발생하는데요..
: :
: : Form의 CloseQuery / Close 이벤트에서
: : Socket을 닫거나 Serial Port를 닫으면서 해당 컴포넌트의 Close 이벤트가 다시 발생하고,
: : 이 이벤트에 대한 로그를 로그 스레드에서 처리하는데, 벌써 메인 폼은 없어져서
: : 로그를 처리할 수 없는 상황이 생깁니다. 그냥 Sleep()으로 기다려도 MainThread가 Sleep()으로
: : 빠져버리니 이것도 해결책이 되지 않더군요.
: :
: : 요지는 CloseQuery / Close 이벤트에서 LogThread가 자신의 로그 내용을 다 적을 때까지
: : 기다려야 할 때 어떻게 하는 지..?
: :
: :
: : //---------------------------------------------------------------------------
: : // Close 관련 Event
: : //---------------------------------------------------------------------------
: :
: : //---------------------------------------------------------------------------
: : void __fastcall TFormMain::FormCloseQuery(TObject *Sender, bool &CanClose)
: : {
: : LogMessage("Software is closeing.....................................");
: :
: : // Socket Release
: : ASocket->Active = false; // Disconnect event 발생 => Log 기록
: : BSocket->Active = false; // Disconnect event 발생 => Log 기록
: :
: : // Serial Port Release
: : SerialPort1->Open = false; // Close Event 발생 => Log 기록
: : SerialPort2->Open = false; // Close Event 발생 => Log 기록
: :
: : // Timer Stop
: : // ....
: :
: : // Other Resource Release
: : // ....
: :
: : // Message pumping
: : //for ( int i = 0 ; i < 10 ; i++ ) {
: : // Application->ProcessMessages();
: : //}
: : CanClose = true;
: : }
: :
: : //---------------------------------------------------------------------------
: : void __fastcall TFormMain::FormClose(TObject *Sender, TCloseAction &Action)
: : {
: : // Resource Release
: :
: : delete pGLogSection;
: : delete GLogQueue;
: : delete GLogEvent;
: :
: : Action = caFree;
: : return;
: : }
: :
: :
: : //---------------------------------------------------------------------------
: : // Log Thread Process
: : //---------------------------------------------------------------------------
: :
: : //---------------------------------------------------------------------------
: : void __fastcall TLogThread::Execute()
: : {
: : TWaitResult Result;
: : STLogMessage *pLogMessage;
: : while ( FormMain->m_bLogThread ) {
: : Result = GLogEvent->WaitFor(EVENT_WAIT_TIME); // wait 1 second
: : if ( Result == wrSignaled || Result == wrTimeout ) {
: : while ( GLogQueue->Count() ) {
: :
: : pGLogSection->Enter();
: : pLogMessage = (STLogMessage *) GLogQueue->Pop();
: : pGLogSection->Leave();
: :
: : LogWrite(pLogMessage);
: : delete pLogMessage;
: : }
: : } else if ( Result == wrAbandoned ) { // Event Object was destored
: : // wrError: An error occured while waiting.
: : // Check the LastError property for an error
: : // code giving more informaiton.
: : } else {
: : // nothing to do..
: : }
: : //G_pSoundEvent->ResetEvent(); // Auto Event Reset mode
: : }
: : }
: :
: : //---------------------------------------------------------------------------
: : void TLogThread::LogWrite(STLogMessage *pLogMessage)
: : {
: : if ( FormMain->Memo->Lines->Count > 100 ) FormMain->Memo->Lines->Clear();
: :
: : TDateTime t = pLogMessage->LogTime;
: : USHORT iHour, iMinute, iSec, iMSec;
: :
: : t.DecodeTime(&iHour, &iMinute, &iSec, &iMSec);
: :
: : UnicodeString sLogMsg;
: : sLogMsg = sLogMsg.sprintf(L"[%02d:%02d:%02d] ",iHour, iMinute, iSec);
: : sLogMsg += pLogMessage->LogMessage;
: :
: : FormMain->Memo->Lines->Insert(0, sLogMsg); // 메인 폼의 로그창에 기록
: :
: : if ( pLogMessage->bFile ) {
: : m_Log.LogMessage(sLogMsg); // 로그 파일에 기록
: : }
: : }
: :
: :