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 :

Exception sur Multithreading


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Par défaut Exception sur Multithreading
    Bonjour à tous et d'avance merci!

    Contexte:
    -Si je comprends bien, mon thread principal gere l'affichage de l'appli
    -Je lance un thread secondaire pour exporter une grid vers XLS

    Questions:
    1-Comment puis je ouvrir le fichier généré par le thread secondaire quand il est terminé? (Quand je tente de l'ouvrir, ca bloque...)

    2-Comment puis-je laisser un evenement de ma grid (thread1) se faire lors de l'export (thread2)
    Je suis un peu perdu.. :s

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Par défaut
    Salut,

    pour le premier point, as tu bien disposé ton stream ou fermé ton fichier ? Si, il n'est pas disposé par le thread createur, tu gardes un handle sur ce dernier et tu te feras jeter si tu tentes de le reouvrir.

    Pour la deuxieme question, je suis pas sur de comprendre. Tu veux, sur un event, laisser une methode sur un autre thread ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Par défaut
    Merci de me répondre

    Tout d'abord, j'utilise des composants (grid par ex) Infragistics(editeur)
    J'ai une methode MaGrid.export(...) qui exporte la grid vers un fichier excel (j'ai donc pas la main sur le stream..)

    Pour ma premiere question:
    Donc je lance cette methode dans mon thread2 (pour eviter un blocage de l'interface)

    Quand j'essai d'ouvri le fichier à la fin de l'execution de mon thread (callBack), ca bloque et puis il fini par l'ouvrir (il doit y a voir un timeout qqpart). Meme le fichier visible dans l'explorateur windows est bloqué. Je me suis dis (a tord peut etre) que je ne pouvais pas ouvrir le fichier dans le thread qui l'a créé.

    Pour ma deuxieme question:
    Lors de l'appel de la methode MaGrid.Export, un evenement est levé (ugvDataGrid_InitializeRow) a chaque ligne. Le pb c'est que j'imagine que ca c'est la propriété du thread principal d'ou l'erreur "Opération inter-threads non valide : le contrôle a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé."

    Une troisieme question en cadeau
    a quoi sert clairement une foonction Delagate, et quel dif entre Invoke(MonDelgate) et MonDelagate.invoke

    Merci encore

  4. #4
    Membre Expert
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Par défaut
    Avec la version VB.NET 2005, des exceptions "Opération inter-threads non valide " sont lévés. Cela signifie que tu essayes d'accéder à un élément de ta form (datagrid, textbox, bouton...) dans un autre thread autre que le thread principal. Une manière de résoudre le problème est d'utiliser la méthode invoke.

    Perso, entre invoke(new NomDelegue(addressof Procedure)) et MonObjet.Invoke(blabla), je ne vois pas de différence
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Par défaut
    Merci
    Pour le pb d'invoke, un me leve une exception et pas l'autre

  6. #6
    Membre Expert
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Par défaut
    Citation Envoyé par emap Voir le message
    Merci
    Pour le pb d'invoke, un me leve une exception et pas l'autre
    lequel lève une erreur ?
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Par défaut
    J'ai essayé de regarder l'aide sur le site de l'editeur (celui la ?), mais j'ai des problemes avec leur fonction d'aide dans la recherche ...

    Bref, pour le premier point, la fonction export() ne serait pas deja une fonction asynchrone ? Ce qui pourrait expliquer les difficultés d'ouverture de ton fichier, la methode retourne mais l'export n'est peut etre pas fini.

    Si Export() a été lancé sur un thread tiers, tous les events qu'il pourrait declencher seront traité par ce thread, ainsi si il leve l'event InitializeRow, le callback assigné (apparement ugvDataGrid_InitializeRow(...) ) sera traité par le thread d'export. Donc si tu dois faire des operations sur des controls dans ce callback, il faudra invoker le thread d'UI pour eviter ton probleme de crossthread (if (InvokeRequired) { [...].Invoke(...) ; } ).

    Enfin pour la derniere question, ca n'a tout simplement rien à voir. =)
    Le premier invoke provient de l'interface ISynchronizeInvoke, la classe Control l'implemente pour permettre justement des invoke depuis un thread tiers. L'autre Invoke (le deuxieme), c'est une methode que possede tous les types delegués qui permet d'appeler la methode pointée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        class Program
        {
            delegate void DelegateString(string s);
     
            static void Main(string[] args)
            {
                DelegateString d = new DelegateString(F);
                d("Coucou"); //est strictement equivalent à d.Invoke("Coucou");
            }
     
            static void F(string s)
            {
            }
        }
    Enfin, une instance d'un type delegué, il faut voir ca comme un tableau dynamique de pointeur de fonction, tu peux en (des ptrs de fonctions) ajouter, en retirer, les appeler etc.. Bref, c'est vraiment la base de la programmation evenementielle.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Par défaut
    merci

    Apparement non, parce que l'export sans passer par un autre thread me bloque l'interface..ca veux dire que c'est le meme thread non?

    Mais alors comment tu fais ca: "il faudra invoker le thread d'UI pour eviter ton probleme de crossthread "

    "tu peux en (des ptrs de fonctions) ajouter, en retirer, les appeler etc.. Bref, c'est vraiment la base de la programmation evenementielle." => ok mais quel interet? pourquoi ne pas pouvoir utiliser simplement la fonction?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Par défaut
    Le mieux serait peut etre que je donne mon code (la je test avec BeginInvoke):

    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
     
        Delegate Function CréerFichier() As ResultatExport
     
        Private Function ToPDF(ByVal sChemin As String, ByVal bOuvrir As Boolean) As String
            ToXLS = ""
     
            If sChemin Is Nothing Then
                Dim svgDlg As New System.Windows.Forms.SaveFileDialog
                svgDlg.AddExtension = True
                svgDlg.Filter = "Fichiers XLS (*.xls)|*.xls"
                svgDlg.FilterIndex = 1
     
                If svgDlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
                    sChemin = svgDlg.FileName
                    isiToXLS = sChemin
                Else
                    Exit Function
                End If
            End If
     
    'Ma grid c'est Me.ugvDataGrid, l'object qui doit faire l'export c'est Me.ugeExportPdf
                   Dim oExportToPdf As New ExportToPdf(sChemin, Me.ugvDataGrid, Me.ugeExportPdf, bOuvrir)
            Dim tA As New CréerFichier(AddressOf oExportToPdf.Export)
     
            tA.BeginInvoke(AddressOf AfficherResultat, tA)
        End Function
     
    Class ExportToPdf
            Private _Chemin As String
            Private _Grid As UltraGrid
            Private _ugePdf As UltraWinGrid.DocumentExport.UltraGridDocumentExporter
            Private _RetourExport As ResultatExport
            Private _Ouvrir As Boolean = False
     
            Public Sub New(ByVal Chemin As String, _
                            ByVal uGrid As UltraGrid, _
                            ByVal ugePdf As UltraWinGrid.DocumentExport.UltraGridDocumentExporter, _
                            ByVal Ouvrir As Boolean)
     
                _Chemin = Chemin
                _Ouvrir = Ouvrir
                _ugePdf = ugePdf
                _Grid = uGrid
            End Sub
     
            Public Function Export() As ResultatExport
                Try
                    _ugePdf.Export(_Grid, _Chemin, DocumentExport.GridExportFileFormat.PDF)
                    Me._RetourExport = New ResultatExport(_Chemin, eTypeRetour.Path, _Ouvrir, Nothing)
     
                Catch ex As Exception
                    Me._RetourExport = New ResultatExport(Nothing, eTypeRetour.Erreur, False, "Impossible de générer un fichier PDF, " & ex.Message)
                End Try
     
                Return Me._RetourExport
            End Function
        End Class
     
     
        Public Sub AfficherResultat(ByVal iAr As IAsyncResult)
            Dim oResultatExport As ResultatExport
            Dim tA As CréerFichier
     
            tA = CType(iAr.AsyncState, CréerFichier)
            oResultatExport = tA.EndInvoke(iAr)
            Invoke(ArreterPrgDelegate)
     
            If Not (oResultatExport.Erreur Is Nothing) Then
                MessageBox.Show(oResultatExport.Erreur, "Export", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Else
                If oResultatExport.Ouvrir Then
                    If MessageBox.Show("Confirmez-vous l'ouverture du fichier généré?", "Export", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) = DialogResult.Yes Then
                        'Dim t As New Thread(AddressOf oResultatExport.OuvrirFichier)
                        't.IsBackground = True
                        't.Start()
                    Else
                        MessageBox.Show("Fichier généré avec succès: " & oResultatExport.Chemin, "Export", MessageBoxButtons.OK, MessageBoxIcon.Information)
                    End If
                Else
                    MessageBox.Show("Fichier généré avec succès: " & oResultatExport.Chemin, "Export", MessageBoxButtons.OK, MessageBoxIcon.Information)
                End If
            End If
        End Sub
     
     Class ResultatExport
            Private _Chemin As String
            Private _TypeRetour As eTypeRetour
            Private _MessageErreur As String
            Private _Ouvrir As Boolean
     
            Public Sub New(ByVal Chemin As String, _
                            ByVal TypeExport As eTypeRetour, _
                            ByVal Ouvrir As Boolean, _
                            ByVal Message As String)
     
                _Chemin = Chemin
                _TypeRetour = TypeExport
                _Ouvrir = Ouvrir
                _MessageErreur = Message
            End Sub
     
            Public ReadOnly Property Ouvrir() As Boolean
                Get
                    Return _Ouvrir
                End Get
            End Property
     
            Public ReadOnly Property TypeRetour() As eTypeRetour
                Get
                    Return _TypeRetour
                End Get
            End Property
     
            Public ReadOnly Property Erreur() As String
                Get
                    Return _MessageErreur
                End Get
            End Property
     
            Public ReadOnly Property Chemin() As String
                Get
                    Return _Chemin
                End Get
            End Property
     
            Public Sub OuvrirFichier()
                If File.Exists(_Chemin) Then
                    Dim proc As New Process
                    proc.StartInfo.FileName = _Chemin
                    proc.Start()
                End If
            End Sub
        End Class
    peut etre que qqc merde la dedans, je suis ouvert a tout vu que je debute avec les thread!

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 01/12/2005, 10h54
  2. Réponses: 5
    Dernier message: 07/07/2005, 10h20
  3. [vb.net] exception sur monForm.Show
    Par graphicsxp dans le forum Windows Forms
    Réponses: 2
    Dernier message: 04/07/2005, 12h27
  4. Exception sur Java Web Start
    Par Le Bressan dans le forum JWS
    Réponses: 5
    Dernier message: 01/02/2005, 10h52
  5. [Tomcat] Exception sur JSP
    Par Malaussene dans le forum Tomcat et TomEE
    Réponses: 7
    Dernier message: 10/09/2004, 08h43

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