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

Windows Forms Discussion :

Comment calculer le temps restant pour une opération d'extraction et/ou compression de fichier (DotnetZip) [Débutant]


Sujet :

Windows Forms

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut Comment calculer le temps restant pour une opération d'extraction et/ou compression de fichier (DotnetZip)
    Bonjour,

    J'ai commencé à développer une application de type Winzip permettant de décompresser les fichiers au format .zip avec la bibliothèque DotNetzip. Pour le moment tout va bien, j'arrive à obtenir une application assez complète (vue treeview et listview), je gère également le Drag and Drop dans les deux sens, etc...
    Durant une opération de compression et/ou décompression j'affiche une fenêtre contenant une barre de progression, ainsi que le nom des fichiers traités. j'aimerai que cette dernière affiche également le temps restant pour l'opération en cours, qui serait actualisé toutes les secondes. Je dispose pour cela de quelques informations dont les 2 principales sont :

    - le nombre total d'octets à décompresser ou à archiver,
    - le nombre d'octets déjà traités (décompression ou compression)

    J'ai beau essayer plein de trucs, impossible d'obtenir un résultat probant.

    Quelqu'un pourrait-il m'apporter une solution.

    Merci d'avance

  2. #2
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    Salut,

    je n'ai jamais essayé de faire ce genre de chose mais je me tente sur une possibilité.
    Au moment du lancement de ton traitement tu récupères le DateTime.Now.
    A chaque refresh de ton "estimation de temps restant" :
    - tu récupères le nouveau DateTime.Now,
    - tu fais la différence avec celui que tu avais récupéré au début,
    - vu que tu connais le nombre d'octets déjà traités tu peux déterminer une la vitesse,
    - tu appliques cette estimation au nombre d'octets restants (octets totaux - octets traités).

    Bon dev.
    Plus je connais de langages, plus j'aime le C.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Merci pour cette réponse, je l'ai mise en pratique et cela fonctionne très bien lorsque c'est une opération effectuée en seule passe (extraction, lecture).
    Il en va tout autrement pour une opération de compression . En effet, DotNetZip effectue cette opération en 2 passes. Et c'est là que les choses se complique énormément pour moi.

    Je dispose de 3 données :

    1) La somme totale en octets des fichiers à compresser (_TotalBytesToTransfer),
    2) Le nombre total de fichiers à compresser,
    3) La somme en octets déjà traitée pour le fichier en cours de compression (e.BytesTransferred)

    Sachant que la donnée 3 est remise à zéro au début de chaque passe et est égale à la somme en octets du fichier à la fin de chacune d'entre elle.
    Je n'arrive pas à trouver l'algorithme qui me permettrait d'avoir un décompte parfait du temps restant et ce quelque soit le nombre de fichiers à traiter et surtout en prenant en compte de ces 2 passes systématiques par fichier.
    Pour info, et pour ceux qui connaissent un peu cette bibliothèque de compression, la donnée 1 correspond bien à la somme en octets de tous les fichiers à traiter (membre perso), à ne pas confondre avec le paramètre e.TotalBytesToTransfer qui lui correspond uniquement à la somme totale du fichier en cours de compression.

    Ce n'est ma méthode (d'extension) qui est en cause car elle fonctionne très bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    private Stopwatch sw = new Stopwatch();
     
    sw.CalcRemainingTime(bytesTransferred, totalBytesToTransfer).ToString(@"hh\:mm\:ss")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
            public static TimeSpan CalcRemainingTime(this Stopwatch sw, long bytesTransferred, long totalBytesToTransferred)
            {
                if (bytesTransferred == 0) return TimeSpan.Zero;
                float elapsedMin = ((float)sw.ElapsedMilliseconds / 1000) / 60;
                float minLeft = (elapsedMin / bytesTransferred) * (totalBytesToTransferred - bytesTransferred);
                TimeSpan resultTime = TimeSpan.FromMinutes(minLeft) + new TimeSpan(0,0,1); // add 1 seconde
                return resultTime;
            }
    N'étant pas du tout un fan des maths quelqu'un pourrait-il m'aider à résoudre cette équation ?

    Merci d'avance

  4. #4
    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
    Points : 3 404
    Points
    3 404
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    Je dispose de 3 données :

    1) La somme totale en octets des fichiers à compresser (_TotalBytesToTransfer),
    2) Le nombre total de fichiers à compresser,
    3) La somme en octets déjà traitée pour le fichier en cours de compression (e.BytesTransferred)

    Sachant que la donnée 3 est remise à zéro au début de chaque passe et est égale à la somme en octets du fichier à la fin de chacune d'entre elle.
    Bonjour,

    Sur la même logique que jopopmk :

    Tu as la somme totale des octets à traité, qui correspond au 100%.
    Pour chaque fichier tu as la somme des octets déjà traité, qui forment partiellement ton avancement. Partiellement car tu n'as, à priori, la visibilité que sur le fichier en cours de traitement.

    Si j'ai bien compris le fonctionnement, à la fin du traitement d'un fichier tu obtiens le nombre d'octets traités pour celui-ci. Pour avoir ton avancement total, il suffit de conserver cette information dans une variable (TotalOctetsFichiers, par exemple) que tu alimenteras à chaque fin de fichier et y ajouter le nombre total d'octets traités pour le fichier en cours de compression.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Merci pour ta réponse mais non, ce n'est pas la solution. En effet, comme je l'ai expliqué la solution que tu donnes fonctionne très bien lorsque l'opération est effectuée en une seule passe.
    j'utilisais d'ailleurs déjà cette solution pour l'extraction (qui nécessite elle qu'une seule passe) à l'inverse d'une opération de compression qui nécessite 2 passes.
    La difficulté est que ces 2 passes durent plus ou moins longtemps pour une quantité d'octets identique, comment évaluer le temps restant dynamiquement sachant que ces 2 passes sont effectuées séquentiellement.

    Je vais tenter d'expliquer le problème via une analogie grossière (j'utilise de simples boucles For pour illustrer ce qui se passe réellement) :

    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
    35
    36
    37
    
    // ATTENTION ! les passes sont effectuées séquentiellement, il s'entend !
    
    private Stopwatch sw = new Stopwatch();
    
    // nb de fichiers à compresser
    for(var x = 1; x < 5; x++)
    {   
        // première passe -> octets à traiter
        for(var y = 0; y < 500000; y++)          ------------------         
        {                                                         |
            DisplayRemainingTime(y);                              |
        }                                                         |
                                                                  |
        // deuxième passe -> octets à traiter                     | L'affichage du temps restant doit pouvoir refléter le temps que prennent ces 2 passes
        for(var z = 0; z < 500000; z++)                           |
        {                                                         |
           DisplayRemainingTime(z);                               |
        }                                                         |
    }                                             -----------------
    
    // Cette méthode est appelée toutes les secondes via un Timer
    private void DisplayRemainingTime(long bytesTransferred)
    {
        sw.CalcRemainingTime(bytesTransferred, _TotalBytesToTransfer).ToString(@"hh\:mm\:ss");
    }
    
    
            public static TimeSpan CalcRemainingTime(this Stopwatch sw, long bytesTransferred, long totalBytesToTransferred)
            {
                if (bytesTransferred == 0) return TimeSpan.Zero;
                float elapsedMin = ((float)sw.ElapsedMilliseconds / 1000) / 60;
                float minLeft = (elapsedMin / bytesTransferred) * (totalBytesToTransferred - bytesTransferred);
                TimeSpan resultTime = TimeSpan.FromMinutes(minLeft) + new TimeSpan(0,0,1); // add 1 seconde
                return resultTime;
            }
    Et pouvoir d'une manière ou d'une autre à partir de ces 2 passes restituer un "Temps restant" fiable. En prenant en compte la somme total d'octets traités et les fichiers restant à compresser.
    Il doit bien exister une solution (un algorithme) permettant de résoudre ce problème. J'ai bien essayé de diviser la valeur bytesTransferred par 2 sachant qu'il y a 2 passes et même diviser celle-ci également par le nombre de fichiers à traiter (ce qui parait logique), mais toutes ces solutions se sont révélées infructueuses

    Si quelqu'un à LA solution, je serais ravi de la connaitre. Merci d'avance...

    Cordialement

  6. #6
    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
    Points : 3 404
    Points
    3 404
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    la solution fonctionne très bien lorsque l'opération est effectuée en une seule passe.
    à l'inverse d'une opération de compression qui nécessite 2 passes.
    La difficulté est que ces 2 passes durent plus ou moins longtemps pour une quantité d'octets identique, comment évaluer le temps restant dynamiquement sachant que ces 2 passes sont effectuées séquentiellement.

    Si quelqu'un à LA solution, je serais ravi de la connaitre. Merci d'avance...
    Je n'y connais rien en extraction/compression, d'où peut être ma difficulté à voir le problème... En quoi l'opération peut fonctionner sur une passe et pas sur deux?

    Et sinon je ne pense pas qu'il y ait "LA" solution, tu ne peux qu'estimé plus ou moins précisément le temps que prendrait la machine à effectuer une opération. Enfin je suppose.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par ZenZiTone Voir le message
    Je n'y connais rien en extraction/compression, d'où peut être ma difficulté à voir le problème... En quoi l'opération peut fonctionner sur une passe et pas sur deux?

    Et sinon je ne pense pas qu'il y ait "LA" solution, tu ne peux qu'estimé plus ou moins précisément le temps que prendrait la machine à effectuer une opération. Enfin je suppose.
    Avant de baisser les bras ne vaudrait-il pas déjà essayer ?

    En attendant si un roi de l'algorithme veut bien se pencher sur ce problème (je fourni un code source qui aidera à comprendre le problème et peut-être à le résoudre).

    Merci d'avance

    Cordialement
    Fichiers attachés Fichiers attachés

  8. #8
    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
    Points : 3 404
    Points
    3 404
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    Avant de baisser les bras ne vaudrait-il pas déjà essayer ?


    Citation Envoyé par sylvebarbe78 Voir le message
    En attendant si un roi de l'algorithme veut bien se pencher sur ce problème (je fourni un code source qui aidera à comprendre le problème et peut-être à le résoudre).
    Par contre on ne pourra pas faire ton boulot à ta place... Si le problème est algorithmique, je te conseilles de poster dans la section prévue à cet effet : general-developpement/algorithme-mathematiques/general-algorithmique

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par ZenZiTone Voir le message

    Par contre on ne pourra pas faire ton boulot à ta place...
    Je n'ai jamais demandé à ce qu'on fasse mon boulot à ma place et je n'ai pas attendu qu'on le fasse pour moi.
    D'autre part tu serais bien avisé de t'exprimer autrement, car un jour viendra ou ça sera toi qui sera demandeur d'une aide et tu seras heureux qu'on te l'apporte...

    A bon entendeur...

    Ceci étant dit, merci pour le lien. J'ai posté mon problème dans ce forum.

    Cordialement

  10. #10
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2008
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2008
    Messages : 233
    Points : 336
    Points
    336
    Par défaut
    Et pourquoi pas un BackgroundWorker ?
    "Hope for the best, but prepare for the worst."

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par casiii Voir le message
    Et pourquoi pas un BackgroundWorker ?
    Merci pour la réponse, mais le problème ne se situe pas au niveau des threads De ce côté-ci tout fonctionne très bien.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Un peu plus de clarté dans le problème rencontré :

    Actuellement le compteur du décompte du temps restant est affiché 2 fois :

    Supposons que la compression d'un fichier d'1 Go prenne en tout et pour tout environ 40 secondes, l'affichage actuel s'effectue comme cela (de seconde en seconde) :

    Première passe : 00:00:20... -> 00:00:15... -> 00:00:00... ->jusqu'à 00:00:00 - Seconde passe : 00:00:20... -> 00:00:15... -> jusqu'à 00:00:00

    Comment réaliser 1 seul affichage partant de 00:00:40 jusqu'à 00:00:00 ?

  13. #13
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2008
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2008
    Messages : 233
    Points : 336
    Points
    336
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    Merci pour la réponse, mais le problème ne se situe pas au niveau des threads De ce côté-ci tout fonctionne très bien.
    Je parlais de mettre ZipProgressEventType.Saving_EntryBytesRead dans un BackgroundWorker pour gérer le timer (du coup solution valable si tu fais 1 ou n passages) ?

    ndlr : Je suis pas un grand spécialiste des BackgroundWorkers mais de ce que j'en ai vu, ça pourrait résoudre le problème.
    "Hope for the best, but prepare for the worst."

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Août 2005
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 123
    Points : 356
    Points
    356
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    Un peu plus de clarté dans le problème rencontré :

    Actuellement le compteur du décompte du temps restant est affiché 2 fois :

    Supposons que la compression d'un fichier d'1 Go prenne en tout et pour tout environ 40 secondes, l'affichage actuel s'effectue comme cela (de seconde en seconde) :

    Première passe : 00:00:20... -> 00:00:15... -> 00:00:00... ->jusqu'à 00:00:00 - Seconde passe : 00:00:20... -> 00:00:15... -> jusqu'à 00:00:00

    Comment réaliser 1 seul affichage partant de 00:00:40 jusqu'à 00:00:00 ?

    Je ne vois pas comment tu pourrais calculer à l'avance le temps de traitement de ta 2ème passe avant que celle-ci ne commence.
    Au pire tu peux faire une estimation en analysant combien de temps met ta 2ème passe par rapport à ta 1ère passe et en faisant le calcul ainsi. Mais ça reste une estimation...

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par mattdef Voir le message
    Je ne vois pas comment tu pourrais calculer à l'avance le temps de traitement de ta 2ème passe avant que celle-ci ne commence.
    Au pire tu peux faire une estimation en analysant combien de temps met ta 2ème passe par rapport à ta 1ère passe et en faisant le calcul ainsi. Mais ça reste une estimation...
    J'ai finalement réussi à résoudre le problème et même été beaucoup plus loin en obtenant une précision redoutable.

    Sujet terminé !

  16. #16
    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
    Points : 3 404
    Points
    3 404
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    J'ai finalement réussi à résoudre le problème et même été beaucoup plus loin en obtenant une précision redoutable.

    Sujet terminé !
    Une petite précision sur la résolution du problème, pour en faire bénéficier la communauté?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment calculer le temps d'exécution d'une fonction
    Par gege2061 dans le forum Télécharger
    Réponses: 0
    Dernier message: 30/11/2010, 16h19
  2. Réponses: 4
    Dernier message: 07/01/2010, 13h14
  3. Aide pour un script qui calcule le temps passé depuis une date
    Par Mooneer dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 25/05/2008, 15h23
  4. comment calculer le temps d'execusion d'une application
    Par ulysse031 dans le forum Langage
    Réponses: 13
    Dernier message: 01/06/2007, 00h11
  5. Réponses: 5
    Dernier message: 07/04/2007, 01h49

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