Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 187

 

Hat jemand eine Lösung mit mehreren Timern gefunden, so dass ich das Rad nicht selbst neu erfinden muss?
Ich glaube nicht, dass die Implementierung durch die Verwendung von Zeigern auf die Funktion kompliziert ist. Es ist unwahrscheinlich, dass sie nicht schon vor mir umgesetzt worden wäre.
Das heißt, die ursprüngliche Aufgabe besteht darin, einen Zeitgeber mit beliebiger Periodizität zu erstellen und ihm eine Funktion zuzuweisen , die das Zeitgeberereignis verarbeitet. Und es kann eine beliebige Anzahl von Timern geben.

Zum Beispiel so:

#include <Timer.mqh> 

CTimer timers;
int x1=0;
int x2=0;

int OnInit()
  {
   timers.NewTimer(500, Sum1);  // создаем новый таймер с периодом обновления 500  милисекунд и функцией-обраточником Sum1()
   timers.NewTimer(2000, Sum2); // создаем новый таймер с периодом обновления 2000 милисекунд и функцией-обраточником Sum2()
   return(INIT_SUCCEEDED);
  }

...

void OnTimer()
  {
    timers.OnTimer();   
  }

//+------------------------------------------------------------------+

void Sum1() { // данная функция вызывает с периодичностью 500 милисекунд
x1++;
if (x1==10) timers.KillTimer(Sum1); // удаляем этот таймер 
}

void Sum2() { // данная функция вызывает с периодичностью 2000 милисекунд
x2++;
if (x2==10) timers.KillTimer(Sum2); // удаляем этот таймер
}
 
Nikolai Semko:

Niemand hat eine Lösung mit mehreren Timern gefunden

Ich bin mir sicher, dass ich es schon vor langer Zeit im KB gesehen habe.
 
fxsaber:
Ich bin mir sicher, dass ich es schon vor langer Zeit im Buy More gesehen habe.

Ich kann es nicht finden. Seltsam.
OK, ich werde es selbst implementieren. Es sollte keine Fallstricke geben. Ich werde es im Buy More veröffentlichen.

 
Nikolai Semko:

D.h. die erste Aufgabe besteht darin, einen Timer mit beliebiger Periodizität zu erstellen und ihm seine Timer-Ereignisbehandlungsfunktion zuzuordnen. Und es kann eine beliebige Anzahl von Timern geben.

eine einfachere Variante nicht ausreicht?

input int            OnTimerMs               = 100;
int OnInit()
{
   EventSetMillisecondTimer(OnTimerMs);
   return(INIT_SUCCEEDED);
}
void  OnTimer()
{
   static uint tickcount_500ms = 0;
   static uint tickcount_1s = 0;
   static uint tickcount_1M = 0;
   uint gettickcount = GetTickCount();
   bool event_500ms  =  gettickcount - tickcount_500ms >= 500;
   bool event_1s     =  gettickcount - tickcount_1s >= 1000;
   bool event_1M     =  gettickcount - tickcount_1M >= 60000;
   

// счетчики 500мс, 1с и 1М
   if(event_500ms)
   {
      tickcount_500ms = gettickcount;
.....
   }

   if(event_1s)
   {
      tickcount_1s = gettickcount;
.....
   }

   if(event_1M)
   {
      tickcount_1M = gettickcount;
......
   }

}

UPD: Und so kann man den fxsaber-Code als Vorlage verwenden

So können Sie dafür sorgen, dass alle Objekte automatisch gelöscht werden https://www.mql5.com/ru/forum/325418/page4#comment_16116740

 
Nikolai Semko:

Ich kann es nicht finden. Seltsam.
OK, ich werde es selbst implementieren. Es sollte keine Fallstricke geben. Ich werde es in das Buy More stellen.

fertig
https://www.mql5.com/ru/code/31306

Multi Timer
Multi Timer
  • www.mql5.com
1. Включите в свою программу класс CTimer 2. Создайте один объект класса СTimer. Например timers. 3. Создайте функции-обработчики необходимых таймеров формата void AnyNameFunction() {....} например с такими именами: 4. Когда вам необходимо создать и запустить таймер, сделайте так из любого места: 5. Когда вам таймер больше не нужен...
 
Igor Makanu:

eine einfachere Version nicht funktionieren würde?

UPD: Ansonsten können Sie den Code von fxsaber als Vorlage verwenden

So können Sie dafür sorgen, dass alle Objekte automatisch gelöscht werden https://www.mql5.com/ru/forum/325418/page4#comment_16116740

Natürlich kann man das auch so machen. Aber weniger lesbar und schwieriger zu verwalten.

 
Nikolai Semko:

gemacht
https://www.mql5.com/ru/code/31306

Es war einmal (ungefähr) so.

Die Verwendung mit Klassen ist unpraktisch.

class CWithTimer {

public:

    void CallMeByTimer();

};

Und ein externer (für die Klasse) Zeitgeber mit Zeigern auf die Funktion ist machtlos.

 
Maxim Kuznetsov:

das war einmal (ungefähr) so.

Die Verwendung mit Klassen ist unpraktisch.

class CWithTimer {

public:

    void CallMeByTimer();

};

Und ein externer (für die Klasse) Zeitgeber mit Zeigern auf die Funktion ist machtlos.

Wenn Sie eine Funktion als Klassenmethode meinen, dann stimme ich zu. Ich habe das gestern selbst festgestellt und bin ratlos, wie ich es herausfinden kann.
Ich möchte diese Klasse innerhalb einer anderen Klasse verwenden, sonst ist der Nutzen sehr begrenzt.
Zumindest ein Singleton muss noch implementiert werden und ein bereits außerhalb der Klasse laufender Timer muss gesteuert werden.
 
Nikolai Semko:
Wenn Sie eine Funktion als Klassenmethode meinen, dann stimme ich zu. Ich habe es gestern selbst herausgefunden und rätsele nun, wie ich da wieder herauskomme.
Ich möchte diese Klasse innerhalb einer anderen Klasse anwenden, sonst ist die Anwendung sehr eingeschränkt.
Zumindest müssen wir ein Singleton implementieren und den Timer kontrollieren, der bereits außerhalb der Klasse läuft.
Im Objekt sollte ein Zeiger auf die Klasse mit dem Timer vorhanden sein.
 
Vladimir Simakov:
Das Objekt muss einen Zeiger auf eine Klasse mit einem Timer enthalten.
Die Frage ist, wie man eine nicht statische Methode der Klasse vom Zeiger ausführt, auch wenn das Objekt einer anderen Klasse (in diesem Fall CTimer) eine Eigenschaft (Variable) dieser Klasse ist. Ist das möglich? Ich fürchte, nein.
Grund der Beschwerde: