動作確認
C++ Builder XE4
メインスレッドがエラーで終了した時にソフトを終了させる実装を考えた。
Main.cpp
Main.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
m_terminate = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
String msg = DateTimeToStr(Now());
OutputDebugString(msg.c_str());
if (m_terminate) {
Close();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
m_thr_main = new TThreadMain(/* CreateSuspend=*/false);
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
if (m_thr_main != NULL) {
m_thr_main->Terminate();
for(int idx=0; idx<5; idx++) {
Sleep(200);
Application->ProcessMessages();
}
}
}
void __fastcall TForm1::SetTerminate()
{
m_terminate = true;
}
Main.h
Main.h
//---------------------------------------------------------------------------
#ifndef MainH
#define MainH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include "ThreadMain.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE で管理されるコンポーネント
TTimer *Timer1;
void __fastcall Timer1Timer(TObject *Sender);
void __fastcall FormShow(TObject *Sender);
private: // ユーザー宣言
bool m_terminate;
TThreadMain *m_thr_main;
public: // ユーザー宣言
void __fastcall SetTerminate();
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
ThreadMain.cpp
ThreadMain.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ThreadMain.h"
#include "Main.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// 重要: VCL におけるオブジェクトのメソッドとプロパティは、Synchronize を使って
// 呼び出されるメソッドでのみ使用できます。たとえば、次のようになります。
//
// Synchronize(&UpdateCaption);
//
// ここで、UpdateCaption は 次のようなコードになります。
//
// void __fastcall TThreadMain::UpdateCaption()
// {
// Form1->Caption = "スレッドで更新されました";
// }
//---------------------------------------------------------------------------
__fastcall TThreadMain::TThreadMain(bool CreateSuspended)
: TThread(CreateSuspended)
{
FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall TThreadMain::Execute()
{
for(int idx = 0; idx < 5; idx++) {
Sleep(1000);
}
Form1->SetTerminate();
String msg = L"finish Execute()";
OutputDebugString(msg.c_str());
}
//---------------------------------------------------------------------------
ThreadMain.h
ThreadMain.h
//---------------------------------------------------------------------------
#ifndef ThreadMainH
#define ThreadMainH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
//---------------------------------------------------------------------------
class TThreadMain : public TThread
{
private:
protected:
void __fastcall Execute();
public:
__fastcall TThreadMain(bool CreateSuspended);
};
//---------------------------------------------------------------------------
#endif
スレッドがExecute()を抜ける時にForm1のSetTerminate()をコールするようにした。
スレッドがForm1に依存してしまう。
closureを使うのも手かもしれない。
スレッドが落ちた時にソフトを終了でなく、スレッドを再起動することもできそう。