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 Presentation Foundation Discussion :

Invalid Operation Exception


Sujet :

Windows Presentation Foundation

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2012
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Invalid Operation Exception
    Bonjour,

    J'ai une erreur qui fait planter mon application "La collection a été modifiée, L’opération d'énumération peut ne pas s’exécuter"

    Je cherche depuis déjà 3 semaines sans trouver de solutions, par contre j'ai réussi a localiser la source, une routine qui sert a mettre jour une Liste d'alarme.

    Mon application tourne 24h sur 24 le plantage est aléatoire, des fois après 1h ou 1 journée...

    Je m'explique:

    -J'ai un automate brancher via un câble Ethernet a mon PC. Qui récupéré des alarmes.

    -Mon logiciel récupère les alarmes est les affiches dans une listview.

    J'ai une routine qui fait le traitement des alarmes:

    Cette routine s’exécute toute les secondes:

    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
    Private Sub GestionAlarme()
     
    Dim ListEtatAlarmeFichier As List(of EtatAlarme) = New List(of EtatAlarme)
    Dim ListEtatAlarmeAutomate As List(of EtatAlarme) = New List(of EtatAlarme)
     
     
    ' Je rempli ma ListEtatAlarmeFichier <-- Lecture de Ma base de donnée binaire fait maiso
    ' Je rempli ma ListEtatAlarmeAutomate <-- Lecture des alarmes automate
     
    'Je fait la comparaison des deux listes pour savoir les alarmes qui on changer d’état (Une alarmes a deux états 1 ou 0 actif ou non actif)
    'en fonction du changement d’état je viens modifier ma base de données binaire pour historiser mes alarmes avec leurs date d'apparition et de disparition
     
    'Juste que la tout va bien
     
    'Voici la partie qui pose probléme: (si je la met en commentaire je n'est pas de plantage)
     
    ''''''''''Debut Creation de la list d'alarme actif'''''''''''''''''
                    If Not (ListEtatAlarmeAutomate.Count = Nothing) Then 'Verification que la lsite ne soit pas vierge
                        ListeAlarmeActif = New WpfObservableCollection(Of LogAlarme)
                        Dim alarmeactif As LogAlarme
                        'ListeAlarmeActif.Clear()
                        For Each element As EtatAlarme In ListEtatAlarmeAutomate
                            If (element.etat = True) Then   'seulement si l'alarmes et active
                                alarmeactif = New LogAlarme
                                alarmeactif.id = element.id
                                theConfig = ConfigMgt.GetInstance()     'Lance l'instance pour faire la lecture de l'XML
                                For Each def As DefautAutomate In theConfig.Defauts
                                    If (element.id = def.Id) Then
                                        alarmeactif.defaut = def.Description    'Charge le nom du defaut
                                    End If
                                Next
                                ListeAlarmeActif.Add(alarmeactif)
                            End If
                        Next
                    End If
                    ''''''''''Fin Creation de la list d'alarme actif'''''''''''''''''

    Voici la déclaration de ma ListeAlarmeActif:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Public Property ListeAlarmeActifValue As WpfObservableCollection(Of LogAlarme)  ' Liste des alarmes active 'wpf
        Public Property ListeAlarmeActif As WpfObservableCollection(Of LogAlarme) 'wpf
            Get
                Return ListeAlarmeActifValue
            End Get
            Set(ByVal value As WpfObservableCollection(Of LogAlarme)) 'wpf
                ListeAlarmeActifValue = value
                NotifyPropertyChanged("ListeAlarmeActif")   'Mise a jour de la variable pour le binding
            End Set
        End Property

    Cette ListeAlarmeActif est afficher dans un userControl qui est une simple listview, voici le code du control AlarmeActif

    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
    Public Class AlarmeActifView
        Private Sub Grid1_Loaded() Handles MyBase.Loaded, ListView1.Loaded, Grid1.Loaded
            ThreadPool.QueueUserWorkItem(New WaitCallback(Function(state As Object)
                                                              Dim b As Binding = New Binding("ListeAlarmeActif")
                                                              b.Source = WatchAlarmeNew.ThreadWatchAlarmeNew()
                                                              MyBase.Dispatcher.BeginInvoke(Function()
                                                                                                ListView1.SetBinding(ListView.DataContextProperty, b)
     
     
                                                                                                Return (Nothing)
                                                                                            End Function)
                                                              Return Nothing
                                                          End Function))
        End Sub
    End Class
    Je continu de chercher, si quelqu'un peut me donner une piste pour résoudre mon probléme sa serait d'un grand renfort.

    Merci.

  2. #2
    Membre habitué Avatar de Thrud
    Profil pro
    Développeur .NET
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Points : 183
    Points
    183
    Par défaut
    C'est parce que ta collection ListEtatAlarmeAutomate doit être modifiée pendant que tu la parcoure. Certainement par un autre thread qui alimente la liste.

    Si ta liste est accédée par plusieurs threads, tu devrais mettre en place de la synchronisation (un lock de la liste par exemple).

    Sinon, plus simplement, tu peux faire une copie de ta collection initiale sur laquelle tu vas itérer.

    Je ne connais pas la syntaxe en VB, mais en C#, tu pourrais faire un ToList() sur la collection :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    foreach (EtatAlarme element in ListEtatAlarmeAutomate.ToList())
    {
    }
    

  3. #3
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2010
    Messages : 148
    Points : 291
    Points
    291
    Par défaut
    Pour compléter ce que dit Thrud, dans une boucle ForEach, tu as un accès en lecture uniquement sur l’élément sur lequel tu boucles, l'erreur doit donc venir de ça.

    Bonne journée.

  4. #4
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2012
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Salut,

    Dans un permiers temps merci pour vos réponses, j'ai déjà vérifier au niveaux des For Each pour être sur de mon coup.


    La déclaration de ma list et faite dans une routine(GestionAlarme) donc en local,
    cette routine est appeler par un seul trhead tout les secondes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim ListEtatAlarmeAutomate As List(of EtatAlarme) = New List(of EtatAlarme)
    'Voir ci dessus
    La liste est déclarer au début de cette routine donc la liste n’existe pas en dehors.
    Âpres avoir remplie la liste dans cette routine je l’énumère une fois si elle existe.

    Aucun autre thread n’appelle cette routine.

    Par précaution je les sécuriser avec un boolean pour éviter l’accès concurrentiel de (GestionAlarme)

    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    Private Sub LogRoutine()   '<-- Declarer en Thread
            Dim theTimer As Timers.Timer
            theTimer = New Timers.Timer(1000)                   'temps entre repetition 1000= 1s
            AddHandler theTimer.Elapsed, AddressOf timeDispath_Tick
            theTimer.Start()
        End Sub
     
        Private Sub timeDispath_Tick()
            GestionAlarme(TheFile)
        End Sub
     
        Dim verify1 As Boolean = False
        Private Sub GestionAlarme(ByVal Fichier As String)
     
            If verify1 = False Then '<-- Verify l'acces concurentiel
                verify1 = True
     
                Try
     
                    Dim ListEtatAlarmeAutomate As List(Of EtatAlarme) = New List(Of EtatAlarme)
     
    'JE REMPLI MA LISTE
                    ''''''''''Debut Lecture automate'''''''''''''''''
                    server.Connect()
                    If (server.Connect = True) Then 'Verification de la presence de la comm entre le pc et l'automate
                        theConfig = ConfigMgt.GetInstance()     'Lance l'instance pour faire la lecture de l'XML
                        For Each def As DefautAutomate In theConfig.Defauts 'lecture des Id qui sont dans le XML
                            IdEtat = New EtatAlarme
                            IdEtat.id = def.Id
                            IdEtat.etat = server.Read(def.Alarme)    'Lecture dans l'automate de l'etat d'une alarme
                            ListEtatAlarmeAutomate.Add((IdEtat))
                        Next
                    End If
                    ''''''''''Fin Lecture automate'''''''''''''''''
     
     
    'JE L'ENUMERE
                    ''''''''''Debut Creation de la list d'alarme actif'''''''''''''''''
                    If Not (ListEtatAlarmeAutomate.Count = Nothing) Then 'Verification que la lsite ne soit pas vierge
                        ListeAlarmeActif = New WpfObservableCollection(Of LogAlarme)
                        Dim alarmeactif As LogAlarme
     
                        For Each element As EtatAlarme In ListEtatAlarmeAutomate
                            If (element.etat = True) Then   'seulement si l'alarmes et active
                                alarmeactif = New LogAlarme
                                alarmeactif.id = element.id
                                theConfig = ConfigMgt.GetInstance()     'Lance l'instance pour faire la lecture de l'XML
                                For Each def As DefautAutomate In theConfig.Defauts
                                    If (element.id = def.Id) Then
                                        alarmeactif.defaut = def.Description    'Charge le nom du defaut
                                    End If
                                Next
                                ListeAlarmeActif.Add(alarmeactif)
                            End If
                        Next
                    End If
                    ''''''''''Fin Creation de la list d'alarme actif'''''''''''''''''
     
                Catch ex As Exception 'Pour debug
                    FileError(DateTime.Now.ToString + "    " + "Erreur GestionAlarme")
                End Try
     
                verify1 = False
     
            Else
                FileError2(DateTime.Now.ToString + "    " + "access concurentiel") 'Pour debug
            End If
        End Sub

    Si je modifie ma liste et que je l’énumère, je ne vois pas ou actuellement. (Je débute)
    Je poste une partie du code pour avoir vos avis expert.

    Je vous en remercie d'avance.

Discussions similaires

  1. [Débutant] Exception system.invalid.operation exception levé
    Par sarrabnh dans le forum ASP.NET MVC
    Réponses: 1
    Dernier message: 09/05/2013, 16h04
  2. invalid Operation Exception
    Par petitours dans le forum C#
    Réponses: 7
    Dernier message: 27/10/2010, 14h38
  3. probleme de invalid parametre exception
    Par Asmod_D dans le forum C++
    Réponses: 12
    Dernier message: 09/04/2009, 17h05
  4. Réponses: 1
    Dernier message: 22/10/2008, 11h29
  5. [JDBC]Invalid Operation : Type de ResultSet
    Par zizou771 dans le forum JDBC
    Réponses: 7
    Dernier message: 10/10/2005, 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