1. #1
    Membre habitué
    Profil pro
    Inscrit en
    juin 2007
    Messages
    314
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juin 2007
    Messages : 314
    Points : 146
    Points
    146

    Par défaut Annulation calcul en cours / watch dog

    Bonjour,

    J'ai un programme en VB.NET qui réalise de nombreux et longs calculs.

    Aussi, j'ai prévu une barre de défilement, et un bouton annuler permettant à l'utilisateur d'interrompre le calcul sans attendre qu'il se termine.

    Voici comment je le gère actuellement :
    - le clic sur le bouton "annuler" met une variable à true
    - au fur et à mesure du calcul, à la fin de chaque étape de calcul :
    - je fait avancer la barre de défilement
    - j'actualise l'affichage et je traite les événements
    - je regarde la valeur de la variable, et si elle est vraie, j'arrête le calcul et je reviens en arrière

    Comme vous l'avez compris la gestion de l’événement "annuler" n'est pas faite en continu.
    Et les étapes peuvent êtres plus ou moins longue, cela dépend des données à traiter. Il est difficile voire impossible de savoir à l'avance quelles seront les étapes les plus longues.

    Je cherche un moyen permettant d'interrompre mon calcul à n'importe quel moment. Pourquoi ?
    Il y a deux raisons :
    - d'abord, les étapes peuvent parfois êtres très longues
    - ensuite et surtout, certaines étapes peuvent planter ou être si longues que cela bloque le logiciel

    Pour ne rien arranger certaines étapes sont des appels de fonctions de DLL, et c'est justement ces étapes là qui plantent ou sont trop longues !

    En fait ce que je cherche à faite, c'est une sorte de "watch dog" pour faire cesser mon calcul :
    - dès que l'utilisateur veut qu'il s'arrête
    - ou s'il est vraiement trop long (option activable par l'utilisateur, avec choix de la durée maxi au bout de laquelle mon logiciel propose de continuer ou d'arrêter)

    Merci

    A bientôt

  2. #2
    Membre expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    octobre 2008
    Messages
    1 651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : octobre 2008
    Messages : 1 651
    Points : 3 423
    Points
    3 423
    Billets dans le blog
    6

    Par défaut

    Bonsoir,

    Regardes dans ta boite a outils il existe le composant backgroundworker.

    ++

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    juin 2007
    Messages
    314
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juin 2007
    Messages : 314
    Points : 146
    Points
    146

    Par défaut

    Bonjour,

    Je viens de regarder un exemple de BackgroundWorker :

    https://msdn.microsoft.com/fr-fr/lib...code-snippet-3

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    Imports System.ComponentModel
     
    Partial Public Class Page
        Inherits UserControl
        Private bw As BackgroundWorker = New BackgroundWorker
     
        Public Sub New()
            InitializeComponent()
     
            bw.WorkerReportsProgress = True
            bw.WorkerSupportsCancellation = True
            AddHandler bw.DoWork, AddressOf bw_DoWork
            AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
            AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted
     
        End Sub
        Private Sub buttonStart_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            If Not bw.IsBusy = True Then
                bw.RunWorkerAsync()
            End If
        End Sub
        Private Sub buttonCancel_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            If bw.WorkerSupportsCancellation = True Then
                bw.CancelAsync()
            End If
        End Sub
        Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
            Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
     
            For i = 1 To 10
                If bw.CancellationPending = True Then
                    e.Cancel = True
                    Exit For
                Else
                    ' Perform a time consuming operation and report progress.
                    System.Threading.Thread.Sleep(500)
                    bw.ReportProgress(i * 10)
                End If
            Next
        End Sub
        Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
            If e.Cancelled = True Then
                Me.tbProgress.Text = "Canceled!"
            ElseIf e.Error IsNot Nothing Then
                Me.tbProgress.Text = "Error: " & e.Error.Message
            Else
                Me.tbProgress.Text = "Done!"
            End If
        End Sub
        Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
            Me.tbProgress.Text = e.ProgressPercentage.ToString() & "%"
        End Sub
    End Class
    En fait cette classe fait la même chose que je fais actuellement

    Dans le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
     
        For i = 1 To 10
            If bw.CancellationPending = True Then
                e.Cancel = True
                Exit For
            Else
                ' Perform a time consuming operation and report progress.
                System.Threading.Thread.Sleep(500)
                bw.ReportProgress(i * 10)
            End If
        Next
    End Sub
    l'annulation ne peut être faire qu'entre les étapes de calcul (ici il y a dix étapes, chacune correspondant au code entre le Else et le End If

    J'aurais aimé trouvé comment faire en sorte que l'annulation puisse se faire "au mileu" du code entre le Else et le End If

    Plus exactement : comment interrompre l’exécution d'une fonction sans être obligé de modifier la fonction en y ajoutant des lignes "if annuler = true then exit function" partout

    A bientôt

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : avril 2007
    Messages : 13 114
    Points : 23 888
    Points
    23 888

    Par défaut

    sur un thread il y a bien thread.abort ou thread.interrupt
    les 2 sont censés arrêter le thread quasi immédiatement

    abort génère une exception, qui remonte tous les catchs (threadabortexception) jusqu'à sortir du thread (sans propager plus l'exception)
    ca doit permettre de gérer proprement l'annulation si nécessaire
    si cette exception se produit dans le framework ca doit pouvoir créer des problèmes (on ne sait pas si des choses sont des états non gérés et potentiellement instable)
    si c'est dans une dll qui n'est pas en .net je ne sais pas ce que ca fait, à tester ...

    interrupt est plus violent, il arrete le thread directement, je ne sais pas non plus quels sont les effets de bords qui peuvent arriver, surement les mêmes ou pire
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    juin 2007
    Messages
    314
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juin 2007
    Messages : 314
    Points : 146
    Points
    146

    Par défaut

    Utiliser un thread pourquoi pas

    Si le calcul est annulé il suffit de revenir en arrière et d'effacer les données créés par le calcul interrompu. D'ailleurs c'est ce que je fait actuellement.

    En effet, il ne faut pas que l'arrêt soit violent, les ressources doivent êtres libérées proprement (par exemple, fermer les fichiers ouverts lorsque le code interrompu est un code qui lit ou écrit un fichier)

    A+

Discussions similaires

  1. [XL-2010] Peut-on interrompre des filtres ou des calculs en cours ?
    Par Denis_67 dans le forum Excel
    Réponses: 7
    Dernier message: 20/10/2016, 14h01
  2. Les configurations minimale et requise de Watch Dogs révélées
    Par LittleWhite dans le forum Développement 2D, 3D et Jeux
    Réponses: 1
    Dernier message: 08/10/2013, 13h04
  3. [XL-2007] Annulation filtres en cours
    Par manuseverine dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 27/08/2010, 17h54
  4. calcul remise cours
    Par chouchouboy dans le forum VBScript
    Réponses: 1
    Dernier message: 15/09/2008, 09h38
  5. Réponses: 5
    Dernier message: 30/06/2007, 11h56

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