0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

c++ builder XE4, 10.2 Tokyo > TTimer > N回リトライする

Last updated at Posted at 2016-08-03
動作確認
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)

動作仕様

  • ある指定のインターバルごとに処理をする
  • 最大N回のリトライをする
  • 成功した時点で処理をやめる

なんらかのインターバル処理が必要となる。

スレッド実装か、TTimer実装など考えられる。

code v0.1

TTimer実装した。

Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *btnStart;
	TCheckBox *chkOK;
	TTimer *Timer1;
	TMemo *Memo1;
	void __fastcall btnStartClick(TObject *Sender);
	void __fastcall Timer1Timer(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

static int s_index;
static const int kMaxRetry = 6;

void __fastcall TForm1::btnStartClick(TObject *Sender)
{
	s_index = 0;
	Memo1->Clear();

	Timer1->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
	String msg = DateTimeToStr(Now());
	Memo1->Lines->Add(msg);

	s_index++;


	if (chkOK->Checked || s_index >= kMaxRetry) {
		Timer1->Enabled = false;
		Memo1->Lines->Add(L"Stop");
	}
}
//---------------------------------------------------------------------------

結果

例として、Timer1->Interval = 5000; // msecとした。

最大回数リトライ

qiita.png

途中で成功した場合

chkOKをチェックして、途中で成功させた場合。

qiita.png

備考

TTimer->Enabled=true;してから最初の1回が開始されるまでインターバルmsec待つことになる。
TTimer->Enabled=true;した時点で処理をしたい場合は、別途処理をコールすることになる。

上記の例ではchkOKによる処理の成功判別としたが、TTimer内の処理自体の成功を判別するようにして使うのを想定している。

TTimer内の処理を長くする設計はまずいので、通常はTTimer内はフラグを立てるだけにしておいて、そのフラグが立っていることを判別して処理を始める、というような使い方も検討するのがいい。組込み系の割込み処理と同じ考え。

code v0.2

処理の成功判断を別クラスから通知することを検討して以下のように変更した。

Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

static int s_index;
static const int kMaxRetry = 6;

void __fastcall TForm1::btnStartClick(TObject *Sender)
{
	s_index = 0;
	Memo1->Clear();

	chkOK->Checked = false;
	Timer1->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
	if (chkOK->Checked == false) {
		String msg = DateTimeToStr(Now());
		Memo1->Lines->Add(msg);
	}

	s_index++;

	if (chkOK->Checked || s_index >= kMaxRetry) {
		Timer1->Enabled = false;
		Memo1->Lines->Add(L"Stop");
	}
}
//---------------------------------------------------------------------------

以下の二通りの方法がある。

  1. chkOK->Checkedを外部クラスからtrueにする
  2. Timer1->Enabledを外部クラスからfalseにする

1の場合は、処理成功後に1回Timer1Timer()がコールされる分、余分である。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?