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

VB.NET Discussion :

Mise a jour d'une IHM sans blocage


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 931
    Par défaut Mise a jour d'une IHM sans blocage
    Bonjour à tous,

    J'ai un petit souci lors d'un portage d'un code VB6 vers VB.net

    Mon logiciel commence à bien tourner, mais j'ai des gros ralentissement, surtout remarqué lorsque j'essaye de déplacer le formulaire. Je le déplace puis il s’arrête avant de repartir.
    Le blocage se fait lorsque le soft rafraîchi les informations que j'ai sur le formulaire.

    Pas facile à expliquer mais je vais essayer:

    Mon logiciel est composer d'un Parent MDI et son menu puis plusieurs enfant possible (Pas afficher en même temps)

    Un timer sur le MDI Parent enclenche la mise à jour de ces menus et du formulaire qui est ouvert, par une interface. l’interface comporte une activation, une désactivation et un tick pour la mise à jour
    A chaque fois j'ai plusieurs 10ene d’élément à mettre à jour (des mesures qui peuvent évoluées, récupérées par une lecture du port COM sur notre supervision)

    Lors du rafraîchissement j'ai donc un blocage de l'IHM pendant 1 a 2 secondes.

    J'ai essayé de passer par un autre timer, qui n'est pas lier au formulaire (System.Threading.Timer).
    Mais bien-sûr ensuite j'ai des erreurs de manipulation interthread des objets graphique.

    Je connais le principe d'invoke et delegate, mais je ne l'ai appliqué que sur des petits projets ou je ne m’était à jour qu'un ou 2 objets, faire un invoque sur chaque objet à mettre à jour me semble pas vraiment optimisé.

    J'ai essayé d'appliquer cela directement à ce qu'il y avait dans le tick de mon ancien timer, cela fonctionne puis j'ai de nouveau le crash interthread après quelque secondes.

    Code d'origine:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    'Dans MDIParent
    Private Sub timerView_Tick(sender As System.Object, e As System.EventArgs) Handles timerView.Tick
       if Connected then
        menu1.enabled = true 
        menu2.enabled = true
      else
        menu1.enabled = false
        menu2.enabled = false
      end if
      Moninterface_active.tick()
      etc...
    End sub
    --------------------------------------------
    'Dans Interface de la form enfant:
    Public sub tick()
      Form1.textbox1.text = ma_mesure1
      Form1.textbox2.text = ma_mesure2
      Form1.textbox3.text = ma_mesure3
      etc...
    End sub
    Code que j'ai essayé et qui fonctionne partiellement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    Private WithEvents TimerWiew As System.Threading.Timer
    Private Delegate Sub TickMeView()
     
    Private Sub MDIForm_Load()
        TimerWiew = New System.Threading.Timer(AddressOf TimerViewMeTo, Nothing, 1000, 250)
    En sub
     
    Private Sub TimerViewMeTo(ByVal state As Object)
        Dim tickm As New TickMeView(AddressOf updateView)
        tickm.Invoke()
    End Sub
     
    Public Sub updateView()
       if Conneted then
        menu1.enabled = true 
        menu2.enabled = true
      else
        menu1.enabled = false
        menu2.enabled = false
      end if
      Moninterface_active.tick()
      'etc...
    End Sub
    Le plantage n’apparaît jamais sur le même Objet.

    Pour obtenir les mesures et informations, je passe par plusieurs classe et boucle sur des collections qui me ralentissent pas mal, faut que j’optimise sa aussi.

    Merci de votre aide.

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    tu peux déja mesurer le temps d'exécution de ton timer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    private _ch as new system.diagnostics.stopwatch
    private _nb as integer 
     
    'sub event tick
    _nb += 1
    ch.Start
    ' ton code
    ch.Stop
    me.text = "nb = " & i.tostring & "  ms = " & ch.elapsedmilliseconds.tostring ' j'ai mis me.text mais le but c'est de l'afficher en titre du form c'est pratique pour du débug, sinon tu attends un peu et tu mets un point d'arret
    'end sub

    ton timer a l'air d'être à 250ms
    donc si au bout de 10 tours tu as plus de 250ms d'écoulé ca veut dire que tu passes déjà la moitié de ton temps ici

    500ms ca me parait suffisant pour de l'interface


    après tu peux aussi tenter le "if pas déjà"
    à savoir remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    machin.text = truc 
    'par 
    if machin.text <> truc then machin.text = truc
    si ca gagne du temps ca vaut le coup
    il me semble que les propriétés du framework appellent un redessin dans tous les cas

    après sinon la conception est peut etre à revoir, qu'est-ce qui fait changer les valeurs ?
    mais dans le principe tu peux techniquement modifier des dizaines de choses plusieurs fois par seconde sans problème, et des centaines avec quelques tricks

    à savoir aussi, le portage d'une appli vb6 vers vb.net doit comporter une conception nouvelle et orientée objet plutot que des copier coller, sinon autant rester sur vb6


    (edit delegate sub c'est has been, et ton invoke doit être fait sur un controle en lui donnant le délégué, pas invoker le délégué directement sinon ca plante)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Le risque de retranscrire du vb6 en vb.net c'est de faire du vb6 implicitement!

    Rien que pour voir vas dans les références et décoches la librairie visual basic.

  4. #4
    Membre éprouvé Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 931
    Par défaut
    Merci à vous pour vos réponses.

    En ce qui concerne les éléments VB6 je fais justement en sorte de ne pas les réutiliser, j'utilise les composants standards du frameworks.
    Nous avions plusieurs dll qui géraient, entre autres, la communication, Dll développé sous Windows 95.
    Maintenant je le fais avec ce que me propose le frameworks. Pour tous les objets graphiques j'ai utilisé les composants .NET, les griddata, treeview, etc..
    On n'a de plus en plus de souci pour installer nos logiciels VB6 chez les clients d'où la conversion.

    Je n'ai pas non plus fait une conversion "copier coller", enfin si, mais pour l'algo, car j'ai été obligé de changer pas mal de choses justement pour travailler en Object.

    Plus j'avançais dans ce projet et plus je me disais qu'il fallait vraiment repenser de A à Z le projet, vb6 permet beaucoup de choses. De plus le projet est important et je ne suis pas l'auteur du projet d'origine, je n'en fais que la maintenance, donc pas mal de fonctionnalité à découvrir dans le code.

    Maintenant pratiquement tout fonctionne, mais je suis en phase d'optimisation. J'ai ajouté plusieurs thread afin de gérer de façon indépendante le chargement de notre base, la gestion de la licence(Dongle), l'idéal serait aussi de faire un thread indépendant pour l'actualisation des données (interrogation sur le Port COM), sa c'est encore dans mon thread principal et cela bouffe du temps, même si je fais en sorte de rafraîchir uniquement ce qu'il y a besoin. Mais certain formulaire on plus de 255 objets graphique, obligé de travaillé en tableau d’objet en VB6, Bien pratique, j'ai reproduit ce problème avec .Net en créant dynamiquement mes objets graphique (par un tableau d'objet) afin de les gérer avec un index (comme vb6), cela facilite l'algo dans des boucles.


    Je vais réduire le rafraîchissement effectivement. Je ne connaissais pas ce system.diagnostics.stopwatch, je vais regarder cela.
    Pour le rafraîchissement, j'ai bien souvent des valeurs de tension, courant, température, à afficher au 100eme, donc les valeurs sont souvent différente à chaque interrogation, c'est imposer par les clients, du 10eme suffirait largement, mais bon.

    Ce que je voulais savoir aussi c'est si je mis prenais bien pour la gestion de l'invoke et delegate? Comme je l'ai dit, je ne l'avais fait que pour un ou deux objets donc je l'avais fait indépendamment avec
    if Control.InvokeRequired then ... sur les objets concernés, mais là il y en a beaucoup.


    Merci

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2013
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 563
    Par défaut
    Citation Envoyé par megamario Voir le message
    Plus j'avançais dans ce projet et plus je me disais qu'il fallait vraiment repenser de A à Z le projet, vb6 permet beaucoup de choses. De plus le projet est important et je ne suis pas l'auteur du projet d'origine, je n'en fais que la maintenance, donc pas mal de fonctionnalité à découvrir dans le code.

    Maintenant pratiquement tout fonctionne, mais je suis en phase d'optimisation.
    Pour ma part j'essayerais de me passer de tous les timers de l'IHM. Pour ma part j'aime bien utiliser un dto qui implémente INotifyPropertyChanged. Ainsi tu t'abonnes au changement de la valeur et ne fais la modification de l'IHM que lorsque tu en as besoin.

    Exemple (en C#, mais le principe est le même) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    public partial class Form1 : Form
        {
            public ObjetMetier MonObjet { get; set; }
            public Form1()
            {
                InitializeComponent();
     
                MonObjet = new ObjetMetier();
                MonObjet.PropertyChanged += (s, e) =>
                {
                    label1.Text = MonObjet.Valeur.ToString();
                };
            }
        }
     
        public class ObjetMetier : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
     
            private int _valeur;
            public int Valeur
            {
                get { return _valeur; }
                set
                {
                    if (_valeur != value)
                    {
                        _valeur = value;
                        PropertyChanged(this,new PropertyChangedEventArgs("Valeur"));
                    }
                }
            }
        }

Discussions similaires

  1. [2.x] Mise à jour d'une page sans vider le cache
    Par christophepradel dans le forum Symfony
    Réponses: 1
    Dernier message: 19/02/2013, 16h41
  2. [AC-2007] Mise a jour d'une table sans modification des identifiants
    Par Nico-SO dans le forum VBA Access
    Réponses: 2
    Dernier message: 18/04/2009, 20h49
  3. Réponses: 4
    Dernier message: 25/04/2006, 19h41
  4. Mise à jour d'une table sans avoir la table
    Par Cablan dans le forum Access
    Réponses: 9
    Dernier message: 26/12/2005, 11h24
  5. mise a jour d'une base a partir d'une autre base
    Par seb3099 dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 18/06/2004, 08h20

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