Bonsoir Ehjoe.
En fait, même si ton code d'exécutait instantanément, il pourrait quand même y avoir un problème avec Timer_Tick. C'est simplement que les tics sont programmés pour arriver toutes les 15,6 ms (même si tu as mis 10ms) et qu'il pourrait en fait s'écouler beaucoup plus de temps entre deux tics. Par exemple, si la machine est occupée, il pourrait se dérouler 50 ou 100ms. Ainsi, la séquence suivante poserait-elle un problème pour ton application ?
* 0ms : Timer1_Tick trouve desdonnées dans le bus -> traitement
* 10ms : aucune nouvelle donnée dans le bus mais le thread est endormi. -> pas d'erreur notifiée alors qu'il aurait fallu.
* 15ms : réception de données dans le bus.
* 35ms : le thread est réveillé et reçoit trois Timer1_Tick (10ms, 20ms, 30ms). Le premier découvre des données dans le bus -> traitement
Ensuite, si tu es certain que ton traitement prend plus de 10ms et que le cas normal et qu'il y ait des données à traiter, l'utilisation d'un timer n'est pas le choix le plus judicieux : sitôt un tic traité, tu vas recevoir tous les tics non-traités d'un coup. Au final, tu entasseras des tics en attente et je ne sais pas très bien sur quoi ça va déboucher (Windows croira t-il que l'application ne répond pas ?) Avec un traitement de 51ms et un thread mono-timer (windows forms par exemple), tu vas avoir la séquence suivante.
* 0ms: Timer1_Tick commence
* 10ms: tic retardé, le thread est occupé, 1 tic en attente.
* 20ms: tic retardé, le thread est occupé, 2 tics en attente.
* 30ms: tic retardé, le thread est occupé, 3 tics en attente.
* 40ms: tic retardé, le thread est occupé, 4 tics en attente.
* 50ms: tic retardé, le thread est occupé, 5 tics en attente.
* 51ms: traitement terminé, début du traitement du tic notifié à t=10ms. 4 tics restant en attente.
* 60ms: tic retardé, le thread est occupé, 5 tics en attente.
Si tu utiliser un timer du type System.Threading.Timer, qui opère sur tous les threads du ThreadPool (16 par défaut), tu vas avoir cinq traitements en parallèle en moyenne, et jusqu'à 16 simultanément après un réveil du thread.
Du coup, il semblerait plus judicieux d'avoir recours au polling : un simple thread avec un code comme celui-ci :
1 2 3 4 5 6 7 8 9 10 11 12 13
|
bool error = false;
while(true)
{
if (DonneesDansLeBus()) Traitement()
else
{
error = true;
break;
}
}
if (error) msg("erreur"); |
Evidemment, si tu dois absolument signaler une erreur dans le cas où aucune donnée n'est présentée au bus dans un intervalle de dix secondes, ce code échouera lui aussi dans certains cas, s'il est endormi à ce moment. Il échouera aussi si ton traitement est finalement plus rapide que dix secondes, il faudra utiliser StopWatch pour vérifier le temps écoulé depuis le dernier relevé avant de signaler une erreur.
PS : La boucle de 1 à 1000 que tu proposes s'éxécuterait en à 1 à 10ns (nanoseconde, milliardième de seconde) si elle était vide et, comme je l'ai expliqué, le plus précis des timers n'a qu'une précision d'une micro-seconde, on ne peut donc pas mesurer une telle durée. Qui plus est, dans le boucle que tu proposais, c'est la lecture du temps machine qui prendrait du temps, et non l'itération/vérification de la boucle.
Partager