IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Timer or not Timer


Sujet :

C#

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 32
    Points : 53
    Points
    53
    Par défaut Timer or not Timer
    Bonjour,

    Je développe actuellement un petit MMO en C# et j'aurais besoin de conseils concernant la gestion des mise à jours de mon monde.

    Résumé rapide du problème :
    Chaque partie du monde est géré par une 'zone' qui connait toutes les entités qui s'y trouvent (joueurs / bâtiments / ...).
    Chaque entité possède une liste d'actions en cours, qui déterminent comment elle va évoluer dans les secondes suivantes (blessure / déplacement / bonus divers, ...)
    Actuellement, chaque 'zone' est un thread séparé qui met à jour chaque action de chacune de ses entités, en boucle (la fréquence de mise à jours est donc potentiellement très variable, ce qui complique la gestion de certaines actions).

    Hors je viens de lire un peu de doc sur Threading.Timer, disant que c'était très économe en processeur pour gérer les événements répétitifs. Je me tâte donc à passer sur un modèle où chaque action aurait son propre timer, qui appellerait sa fonction de mise à jours à intervalles fixes (ou pas, suivant l'action).
    Le problème est que cela va rapidement faire énormément de timers - même avec seulement 500 entités, à raison de 2-3 actions par entités, on atteint des chiffres qui vont au-delà des cas parlant de la fonction Timer sur internet.

    Donc ma question est : les timers restent-ils une solution efficiente lorsqu'on les utilisent massivement (de l'ordre de plusieurs milliers simultanément), ou bien vaut-il mieux que je garde mon modèle actuel ?

    Merci.

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    plus de 3 timer ca me semble trop ...

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    A vrai dire je ne vois pas trop l'intérêt d'utiliser des timers ici, ni même des threads : tu peux très bien avoir un seul thread qui traite les actions de chaque zone, chacune à son tour :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while(true)
    {
        foreach (var zone in zones)
        {
            zone.ExecuteNextAction();
        }
    }

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 32
    Points : 53
    Points
    53
    Par défaut
    Si j'utilise un thread par zone c'est pour tirer parti des machines multi-coeurs, ce qu'on ne peut pas obtenir avec une boucle unique (les zones sont grandes et peu nombreuses : 7-8 au maximum).

    Quand à l'intérêt des timers, ça aurait été d'économiser des vérifications inutiles et de simplifier le code.
    Actuellement si un bonus dure 2 heures je vérifie quand même toutes les X msecondes si il est fini. Idem pour tout un tas d'autre actions qui n'ont pas besoin d'être mise à jours aussi souvent mais qui sont mélangées avec d'autres qui elles en ont besoin. Du coup j'aimerai quitter les modèles à base de 'boucle où l'on met tout le monde à jours'.

    Mais si comme le dit Pol93 les timers C# sont inutilisables à grande échelle, je vais peut être bricoler mes propres timers ... peut être un Dictionnary liant un DateTime et un Delegate vers la fonction de mise à jours de l'action que le thread de la zone lirait, en se mettant en pause quand aucune action n'est proche.

  5. #5
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    pourquoi vérifier quelque chose, un évènement à la fin du bonus conviendrait il ?

    les timers sont peut etre utilisables à grande échelle, mais c'est surtout qu'arrivé là ça relève souvent du problème de conception

    couche graphique ?

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 269
    Points : 460
    Points
    460
    Par défaut
    Bonjour,

    La solution des Timer n'est pas vraiment viable, un Timer reste un thread, et on est limité en nombre de thread.

    Si ton but est de faire chuter la consommation CPU quand tu n'as rien a faire.
    Une liste l'action, un AutoResetEvent qui est lancer à chaque modif de la liste, et en debut de boucle tu attend l'event avec un timeout.

  7. #7
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 317
    Points
    13 317
    Par défaut
    Citation Envoyé par antoine.debyser Voir le message
    on est limité en nombre de thread.
    A combien ?

    Il est vrai que j'ai eu parfois des problèmes au delà de 400 à 500 .... mais c'était un problème de resources.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    312
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 312
    Points : 411
    Points
    411
    Par défaut
    Mets en place un système d’évènement.

    Chacun poste ses évènements en fonction de ce dont il a besoin et quand il en aura besoin.

    Un gestionnaire distribue tout ces trucs a qui en a besoin le moment voulu.

    A mon sens, ça simplifiera également ta conception et tes dépendances.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 32
    Points : 53
    Points
    53
    Par défaut
    Ben le problême des events, c'est justement qu'on ne peut faire le RaiseEvent qu'au moment où l'on souhaite le déclenchement, non ? Donc dans le cas d'un bonus de X heures il faudrait quand même vérifier régulièrement si on est à la fin, ce que j'aimerai justement éviter ... ou alors il y a un moyen de raise un event 'à retardement' ?

    Chacun poste ses évènements en fonction de ce dont il a besoin et quand il en aura besoin.
    Un gestionnaire distribue tout ces trucs a qui en a besoin le moment voulu.
    Du style : une liste triée dont chaque maillon contient le DateTime de déclenchement de la mise à jours, et un pointeur sur l'action concernée (avec mes 'zones' qui executent le premier élement de la liste si la date est atteinte et se mettent en pause sinon) ?

  10. #10
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    on en sait pas assez sur ton code
    mais normalement tu as des classes non graphiques, des threads et des classes qui gère l'affichage
    pour ton bonus, il faut stocker quelque part la date de fin, et il te faut un thread qui parcourt tous les items pour regarder si la date est passée
    tant qu'il n'y a rien de graphique tu peux faire des milliards de chose à la seconde ca ne pose pas de soucis
    si tu utilises des interfaces, tu peux même coder des vérifications différentes dans chaque classe et le thread n'a pas à savoir ce qui va se passer quand il va appeler la méthode qui s'en occupe

    après sur la classe non graphique quand tu désactive le bonus, là il faut un event ou autre qui avertisse la couche graphique

  11. #11
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 269
    Points : 460
    Points
    460
    Par défaut
    A combien ?

    Il est vrai que j'ai eu parfois des problèmes au delà de 400 à 500 .... mais c'était un problème de ressources.
    Ça dépend de ce que tu fais, mais ce post explique bien le problème
    http://blogs.msdn.com/b/oldnewthing/...29/444912.aspx
    Et il est aussi vrai pour du natif que du managé, on la même taille de stack par défaut ^^
    Le threadpool peut être une solution, mais là le framework pose une autre limite (même si on peut la redéfinir) si ma mémoire est bonne c'est quelques chose comme ca.
    • 25 par coeur .net 2.0
    • 250 par coeur .net 3
    • 1023 en .net 4.0 (32 bit)
    • 32767 en .net 4.0 (64bit)

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    312
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 312
    Points : 411
    Points
    411
    Par défaut
    Ben le problême des events, c'est justement qu'on ne peut faire le RaiseEvent qu'au moment où l'on souhaite le déclenchement
    Ah quand je dis évènement je parle pas au niveau technique mais au niveau concept.

    T'as un type Event et chaque module s'inscrit aupres du gestionnaire d'évenement.

    Mais basiquement tu t'en sors avec des types, des appels de methode et eventuellement un peu d'IOC pour faciliter tes découpages.

    Les lecture sur le net au sujet des archis evenementielles sont nombreuses.

Discussions similaires

  1. void (timer::)()' does not match `void (*) ?
    Par jahmanzaar dans le forum Débuter
    Réponses: 5
    Dernier message: 23/10/2008, 16h49
  2. Timer or not timer?
    Par Petit padawan dans le forum VB.NET
    Réponses: 5
    Dernier message: 02/07/2007, 20h12
  3. [javax.swing.Timer] Arrêter mon Timer
    Par GLDavid dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 17/01/2006, 15h26
  4. [débutant] Timer inférieur à 1ms ? Timer + précis ?
    Par hepar dans le forum C++Builder
    Réponses: 6
    Dernier message: 19/02/2004, 18h42
  5. [][Timer] Créer un Timer sans utiliser le composant
    Par HPJ dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 01/10/2003, 11h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo