c++ builder XE4, 10.2 Tokyo > TTimer > N회 재시도

동작 확인
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)

동작 사양


  • 특정의 지정된 간격마다 처리한다
  • 최대 N회 재시도
  • 성공한 시점에서 처리 중지

  • 어떤 간격 처리가 필요합니다.

    thread 실장인가, TTimer 실장등 생각할 수 있다.

    코드 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이었다.

    최대 횟수 재시도





    중간에 성공하면



    chkOK를 체크하고, 도중에 성공시켰을 경우.



    비고



    TTimer->Enabled=true; 하고 나서 처음 1회가 개시될 때까지 インターバルmsec 기다리게 된다.
    TTimer->Enabled=true;한 시점에서 처리를 하고 싶은 경우는, 별도 처리를 호출하게 된다.

    상기의 예에서는 chkOK에 의한 처리의 성공 판별로 했지만, TTimer내의 처리 자체의 성공을 판별하도록 해 사용하는 것을 상정하고 있다.

    TTimer내의 처리를 길게 하는 설계는 좋지 않기 때문에, 통상은 TTimer내는 플래그를 세우는 것만으로 해 두고, 그 플래그가 서 있는 것을 판별해 처리를 시작한다, 라고 하는 사용법도 검토하는 것이 좋아. 임베디드 시스템의 인터럽트 처리와 같은 생각.

    코드 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");
        }
    }
    //---------------------------------------------------------------------------
    

    다음 두 가지 방법이 있습니다.
  • chkOK->Checked를 외부 클래스로부터 true로 한다
  • Timer1->Enabled를 외부 클래스로부터 false로 한다

  • 1의 경우는, 처리 성공 후에 1회 Timer1Timer()가 콜되는 분, 여분이다.

    좋은 웹페이지 즐겨찾기