Deux thread dans le même objet (problème lors de la déstruction de mon objet) [Résolu]

Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 29 juil. 2010 à 12:17 - Dernière réponse : foliv57 423 Messages postés vendredi 17 novembre 2006Date d'inscription 15 juillet 2014 Dernière intervention
- 30 juil. 2010 à 19:25
Bonjour ,
Je suis débutant en multithreading et un détail (qui m'embête beaucoup) me pose problème :

J'améliore en ce moment une classe Journal (c'est d'ailleurs la seconde question que je pose sur ce sujet, la 1ér concerne ma pile mais je pense que le problème est réglé ici pour en savoir plus )

Mon objectif est :
- Quand je crée un objet de ma classe je crée et je démarre un thread supplémentaire dédier à l'écriture de mon fichier (car cela ralenti ÉNORMÉMENT mes programmes lorsque beaucoup d'erreur sont remontées coup sur coup).

- Quand je reçois un message à écrire j'envoie un événement à mon thread pour l'informé que une/des ligne/s est/sont à écrire dans le fichier.

- Quand je détruit mon objet je dit à mon thread de se stopper.

Soit le code (je ne poste pas les délégués pour éviter de surcharger) :
Déclaration de ma variables :
Private ThreadEcriture As System.Threading.Thread
Private StopThreadEcriture As Boolean
Private TickThreadEcriture As New System.Threading.AutoResetEvent(False)


Lors de la création de mon objet :
ThreadEcriture =  New System.Threading.Thread(AddressOf SubThreadEcriture)
ThreadEcriture.Start()


Une fois que j'ai ajouter ma ligne à écrire dans ma pile :
TickThreadEcriture.Set()


Le code de la procédure exécutée dans le thread (StopThreadEcriture est en réalité lut par déléguer mais encore une fois j'évite de surcharger pour plus de lisibilité) :
Private Sub SubThreadEcriture()
   [...]
   While Not StopThreadEcriture()
      TickThreadEcriture.WaitOne()
      'Ici j'écris dans mon fichier temps que ma pile n'est pas vide
   End While
   [...]
End Sub


Lors de la destruction de mon objet :
Protected Overrides Sub Finalize()
   StopThreadEcriture  = True
   TickThreadEcriture.Set()
   ThreadEcriture.Join()
   [...]
End Sub


Logiquement en fessant comme sa ma pile sera vide au moment de la destruction de mon objet et mon thread supplémentaire se termineras sans problème ni erreur (enfin logiquement je suis débutant en multithreading)

Problème temps que mon thread est en exécution je ne reçois pas l'événement Finalize de ma classe. Donc le thread ne s'arrête jamais . Je voudrais éviter d'imposer aux utilisateur de ma classe d'exécuter une procédure "Termine écriture" avant de détruire l'objet.

Comment faire sa ? Parce que là je suis obliger d'utilisé des chemins détournés qui ne me plaise pas du tout, soit de recréer et redémarrer un thread à chaque ajout de ligne dans mon journal si le thread n'est pas en cour d'exécution puis de tester si ma pile est effectivement vide lors de la destruction de l'objet (car il est possible que au moment ou je test si le thread d'écriture est actif il soit entrain de fermer le stream sur le fichier en non encore en cours d'écriture. Donc oui le thread est actif mais ce n'est pas pour autant que l'écriture dans mon fichier sera réellement actif, enfin je ne sait pas si je suis vraiment claire là dessus)

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Afficher la suite 

12 réponses

Répondre au sujet
foliv57 423 Messages postés vendredi 17 novembre 2006Date d'inscription 15 juillet 2014 Dernière intervention - 30 juil. 2010 à 12:38
+3
Utile
Alors,

Pour la question de la finalization de l'objet. Vous pouvez implémenter l'interface IDisposable dans votre classe. Vous aurez des methodes comme ci-dessous, dans lesquels placer votre demande de fin de thread.

Public Class Class1
    Implements IDisposable

    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then

            'Placez ici le code pour terminer le thread

            If disposing Then
            End If

        End If
        Me.disposedValue = True
    End Sub

'J'ai effacé une partie du code généré par l'interface pour gagner de la place

End Class


Ensuite deux possibilités :
1) Si vous créez l'instance de votre classe dans une form, meme remarque que la dernière fois, dans la methode Dispose de la form faite un maClass.Dispose()
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try

            'Ici on détruit notre classe
            maClass.Dispose()
      
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
End Sub


2) Si l'instance de votre classe est faite en public dans un module, vous pourez utiliser l'evenement de fin d'application pour la détruire
Namespace My

    Partial Friend Class MyApplication

        Private Sub MyApplication_Shutdown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shutdown
             monModule.maClass.Dispose()
        End Sub

    End Class

End Namespace


Ensuite pour les autres points je vais détailler
Je suis en test sur la propriété IsBackground (qui, enfin si j'ai bien compris, permet d'autorisé le système à tué le tread lorsque le contenant n'est plus référencé)


Il est préférable de ne pas tuer volontairement un thread. Un thread doit, dans le meilleur des cas, toujours ce terminer de facon controlé. Votre exemple est d'ailleur parlant sur le sujet, il ne faudrait pas que par erreur le thread soit tué alors qu'il reste des données à écrir. Donc le While true n'est pas une bonne solution. Il faut maitriser l'arret.

Pour la partie de code
While MyControl.Invoke(GetCountPileAEcrireMethod) > 0
      Try
         MyStreamWriter.WriteLine(MyControl.Invoke(GetLigneEcrireMethod))

La je dirai que c'est pas bon. Comprenez bien que lorsque vous faite un .Invoke() vous faite appelle à un Delegate qui va à son tour créer un nouveau thread. Donc dans votre thread vous créez, à chaque while, deux thread pour accéder à votre Queue.
Si vos fonctions "GetCountPileAEcrireMethod" et "GetLigneEcrireMethod" sont défini dans la classe, appelez les directement. Elles seront exécuté au sein de votre thread, donc pas de souci.

Donc voila tout (pour le moment) sauf que je crains une erreur (perdre la dernière ligne de mon journal)

C'est aussi pour cette raison que je vous ai posté mon code. Car dans l'exemple que je vous ai fourni, le thread vie tant qu'il y a des données à écrirent.

(enfin objet vue que, sauf erreur de ma part, tout est des objets en .NET)


Non, en .Net il y a deux types.
1) Les types valeur (integer, boolean, structure ....)
2) Les types référence (string "et oui... ", Class ....)

J'extrais de ma pile les données par une Fonction (appelé par déléguer, nommé "GetLigneEcrireMethod") qui exécute le verrou ("SyncLoock") extrais une ligne puis déverrouille ma pile


Vos fonctions "GetCountPileAEcrireMethod" et "GetLigneEcrireMethod" sont très bien car, comme vous le dite, elle ne bloque la queue que le temps d'extraction d'une donnée. Mais comme je l'ai dit au dessus, ne les appelez pas par un delegate, c'est inutile puisque vous êtes deja dans un thread à part.

Il existe peut être mieux que sa en .NET (j'utilise le framwork 3.5 ) ?


La seule autre methode qui me vienne à l'esprit comme ca est l'utilisation de l'objet "Trace" exemple:
Trace.Listeners.Clear()
Trace.Listeners.Add(New TextWriterTraceListener("C:\log.txt"))
Trace.TraceError("Une erreur est survenue") 'Il existe aussi des methodes Write et WriteLine
Trace.Flush()

Mais je ne suis pas sur qu'elle garantisse un tratement ultra performant des écritures. Je ne l'ai jamais mis dans ses derniers retranchement s

Voila, en esperant que ce roman va vous aider à y voir plus clair.
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de foliv57
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 30 juil. 2010 à 16:50
+3
Utile
Juste pour info (et pour vous éviter de lire nos romans à foliv57 et à moi) :
La façon de je gère la propriété IsBackground de mon thread (afin qu'il se termine quand l'objet référencent ce thread est détruit) :

ATTENTION CE N'EST PAS L'IDÉALE la méthode de foliv57 est plus propre que la mienne (mais sa ne correspond pas exactement à mes besoins)

Dans l'ajout de ligne :
SyncLock (TickThreadEcritureHaveOneLock) 'Cette ligne est tres importante elle permet d'interdire au thread de recommencé une boucle temps qu'une ligne est encours d'ajout dans la pile
    'Interdit au système de tué le thread si l'objet le contenant n'est plus référencé
    ThreadEcriture.IsBackground = False
    'Attend le déverrouillage de la pile (si elle est verrouillé) et la verrouille
    SyncLock (PileAEcrire.SyncRoot)
        'Ajoute la ligne construite dans la pile d'écriture
        PileAEcrire.Enqueue(LigneJournal)
    End SyncLock
    'Indique qu'un (ou plus) TickThreadEcriture.Set() à été exécuter
    P_TickThreadEcritureHaveOne =  True
    'Évènement déclenchant le fonctionnement du thread d'écriture fichier
    TickThreadEcriture.Set()
End SyncLock


Dans la procédure d'exécution de mon thread :
While True
    If Not TickThreadEcritureHaveOne Then
'Autorise le système à tue le thread si l'objet le contenant n'est plus référencé
        System.Threading.Thread.CurrentThread.IsBackground  = True
    End If
    'Attend l'exécution d'un TickThreadEcriture.Set()
    TickThreadEcriture.WaitOne()
    'Indique que le thread à reçu le TickThreadEcriture.Set
    TickThreadEcritureHaveOne = False
    'Si il y à des lignes à écrire (évite d'ouvrir le fichier pour rien)
    If GetCountPileAEcrire() > 0 Then
        Try
            'Ouvre le fichier
            AccesseurFichier =  New System.IO.StreamWriter(NomFichierJournal, True, Config.CodePageJournal)
        Catch ex As Exception
            'Remonté de l'exception à finir
            Return
        End Try
        'Temps qu'il y à des lignes à écrire
        While GetCountPileAEcrire() > 0
            Try
                'Lit la pile et écrit le fichier
                AccesseurFichier.WriteLine(GetLigneEcrire())
            Catch ex As Exception
                'Remonté de l'exception à finir
                AccesseurFichier.Dispose()
                AccesseurFichier.Close()
                Return
            End Try
        End While
        'Ferme le fichier
        AccesseurFichier.Close()
    End If
End While


Remarque :
Certaine fonction et propriété utilise des verrouillages pour éviter que plusieurs thread lise ou écrive dans la même donnée en même temps
Private Property TickThreadEcritureHaveOne() As Boolean
    Get
        SyncLock (TickThreadEcritureHaveOneLock)
            Return P_TickThreadEcritureHaveOne
        End SyncLock
    End Get
    Set(ByVal value As Boolean)
        SyncLock (TickThreadEcritureHaveOneLock)
            P_TickThreadEcritureHaveOne  = value
        End SyncLock
    End Set
End Property

Private Function GetCountPileAEcrire() As Integer
    SyncLock (PileAEcrire.SyncRoot)
        Return PileAEcrire.Count
    End SyncLock
End Function
Private Function GetLigneEcrire() As String
    SyncLock (PileAEcrire.SyncRoot)
        Return PileAEcrire.Dequeue
    End SyncLock
End Function


Alors je qui d'accord pour dire que cette façon de faire n'est pas l'idéale (car comme le dit foliv57 "Un thread doit, dans le meilleur des cas, toujours ce terminer de facon controlé.", mais en même temps on ne peut pas vraiment dire que je ne contrôle pas comment mon thread vas se terminer.

Sauf si je trouve mieux (ou qu'un/e CodeSourceien/ne n'est mieux) voila comment je vais contrôler la mort de mon thread (fait comme sa car il n'y à rien à faire à l'extérieur de l'objet au moment de sa mort )

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Polack77
foliv57 423 Messages postés vendredi 17 novembre 2006Date d'inscription 15 juillet 2014 Dernière intervention - 29 juil. 2010 à 21:19
0
Utile
Rebonjour,

N'utilisez pas la methode Finalize.

Ouvrez le fichier FormX.Designer.vb si votre code se trouve dans une form. Dans ce fichier vous trouverez la methode Dispose overridé :
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try

            StopThreadEcriture = True
            TickThreadEcriture.Set()
            ThreadEcriture.Join()
                        
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
End Sub


Un petit conseil aussi. Quand je fais ce genre de chose je rajoute toujours :
Dim stoped As Boolean = ThreadEcriture.Join(30000)
If Not stoped Then ThreadEcriture.Abort() '+ Génération d'une erreur

Ceci afin de ne pas se mettre les utilisateurs à dos si un jour il y a vraiment un problème pour terminer le thread normalement
Commenter la réponse de foliv57
foliv57 423 Messages postés vendredi 17 novembre 2006Date d'inscription 15 juillet 2014 Dernière intervention - 29 juil. 2010 à 21:54
0
Utile
Juste pour culture perso, voici une autre facon de faire :
Public Class Form1

    Private fifo As Queue
    Private StopProcess As Boolean
    Private i As Long
    Private threadProcess As Thread

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'Création de la Queue
        fifo = New Queue()

        'Initialisation
        StopProcess = False
        i = 0

        'Début du process de lecture
        threadProcess = New Thread(AddressOf DequeueProcess)
        threadProcess.Start()

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        'Ajoute un message
        SyncLock fifo.SyncRoot
            fifo.Enqueue("Message " & i.ToString())
        End SyncLock
        i += 1

    End Sub

    Private Sub DequeueProcess()
        Dim messageReceived As Boolean = True
        Dim message As String = ""

        'Tant que le process n'est pas arreté volontairement ou 
        'qu'il y a des éléments dans la Queue
        While (Not StopProcess) Or messageReceived
            messageReceived = False

            'On limite au maximun les actions au sein du verrouillage
            'afin de bloquer la queue le moins longtemps possible
            SyncLock fifo.SyncRoot

                'Test s'il y a des messages à récupérer
                If (fifo.Count <> 0) Then
                    'On récupère un message
                    message = CType(fifo.Dequeue(), String)
                    messageReceived = True
                End If

            End SyncLock

            'Si un message a été récupéré, on effectue ici 
            'le traitement qui prend du temps comme ca le thread
            'principal peut toujours ajouter des éléments à la queue
            If messageReceived Then Console.WriteLine(message)

            Thread.Sleep(10)
        End While

    End Sub

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try

            'Force la fin du processus de réception
            StopProcess = True
            Dim stoped As Boolean = threadProcess.Join(30000)
            If Not stoped Then threadProcess.Abort()

            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If

        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

End Class


Le principe est que le thread est en permanence en train de scruter la queue tant qu'on ne l'arrete pas et qu'il y a des éléments à traiter. On limite au maximum les actions verouillant la queue afin de ne pas bloquer le thread principal.

Je vous post cette methode car vous avez décrit ceci :
While Not StopThreadEcriture()
    TickThreadEcriture.WaitOne()
    'Ici j'écris dans mon fichier temps que ma pile n'est pas vide
End While


Si par "Ici j'écris dans mon fichier temps que ma pile n'est pas vide" vous voulez dire que vous faite une boucle qui vide tous les éléments de la queue, vous risquez de bloquer l'ajout au niveau du thread principal et donc avoir à nouveau des ralentissements.

Je me trompe peut-être ...
Commenter la réponse de foliv57
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 30 juil. 2010 à 11:15
0
Utile
Décidément vous m'aidé sur tout les sujets "foliv57" MERCI

Arf non je ne suis pas dans une form mais dans une classe, donc pas de "X.Designer.vb" (mais merci de l'info je me la met sous le coude pour plus trad )

Oui j'ai pensé à la gestion d'erreur mais je ne pensais pas la faire comme sa, car sauf à l'ouverture du fichier ou au moment où je vide la pile et que j'écris le fichier, je ne voie pas trop ce qui pourrais se produire comme erreur. De plus il est indispensable d'avoir le journal au complet au moment de la fermeture des applications utilisant cette classe. Donc admettons que la machine exécutant ce code soit ÉNORMÉMENT occupé, il est possible que le délais que j'aurais choisi pour vidé la pile ne soit pas suffisant, même si 30 secondes devrais être LARGEMENT suffisant je le reconnais. L'étape suivante de cette amélioration est justement la gestion d'éventuelle erreur (vous avez un coup d'avance ).

Je suis en test sur la propriété IsBackground (qui, enfin si j'ai bien compris, permet d'autorisé le système à tué le tread lorsque le contenant n'est plus référencé). Un petit détail me pose encore problème mais je pense avoir une solution, je m'explique :

Mes variable :
Private MonThreadEcriture =  System.Threading.Thread
Private TickThreadEcriture As New System.Threading.AutoResetEvent(False)


Sur l'événement "New" de ma classe :
MonThreadEcriture  = New System.Threading.Thread(AddressOf SubThreadEcriture)
MonThreadEcriture.Start()


Mon thread principale :
MonThreadEcriture.IsBackground =  False
'Ajout d'une ligne dans ma pile
TickThreadEcriture.Set


La procédure exécuter par le thread :
Dim MyControl As New Control 'Je n'est pas trouvé d'autre façon de faire pour pouvoir utilisé le "Invoke" :'(
Dim MyStreamWriter As System.IO.StreamWriter
While True 'Inutile d'avoir une variable pour tué le thread si j'utilise la propriété IsBackground (enfin il me semble ^^)
   System.Threading.Thread.CurrentThread.IsBackground  = True
   TickThreadEcriture.WaitOne()
   Try
      MyStreamWriter = New System.IO.StreamWriter(MonFichierJournal, True, MyEncoding)
   Catch ex As Exception
      'J'informe mon thread principale de l'erreur (je n'est pas encore cherché comment faire mais sa ne m'inquiète pas trop)
      Return
   End Try
   While MyControl.Invoke(GetCountPileAEcrireMethod) > 0
      Try
         MyStreamWriter.WriteLine(MyControl.Invoke(GetLigneEcrireMethod))
      Catch ex As Exception
         'J'informe mon thread principale de l'erreur
         Return
      End Try
   End While
   MyStreamWriter.Close()
End While


Donc voila tout (pour le moment) sauf que je crains une erreur (perdre la dernière ligne de mon journal) dans le cas où :
- Mon thread principale ajoute une ligne dans la pile au moment de la fermeture de stream de mon thread d'écriture.
- Donc mon thread d'écriture vas être forcé en IsBackground True et rester dans cette état au vue du code (et ajouter "System.Threading.Thread.CurrentThread.IsBackground False" en dessous de la ligne "TickThreadEcriture.WaitOne()" ne fait que déplacer le problème, enfin je pense)

Dans cette état si le programme se termine patatra je n'aurais pas écrit la dernière ligne insérer (ou pas au complet ce qui est presque pire )

La solution pourrais être de testé une varaible "HaveOne" (en plus du "WaitOne") ainsi je pourrais tester si mon objet "TickThreadEcriture" à un coup d'avance et ne pas passé mon thread en IsBackground (sauf que cette propriété n'existe pas et que je ne peut pas hérité de la classe "AutoResetEvent").

Je pensais donc (simplement) ajouter une variable Boolean à ma classe ("TickThreadEcritureHaveOne" par exemple) pour ne pas passé mon thread en IsBackground si une ligne TickThreadEcriture.Set à été exécuter alors que le thread d'écriture n'attendais pas l'événement (j'espère être claire là dessus ) . Il faut maintenant que je place correctement mes verrous sur cette variable (enfin objet vue que, sauf erreur de ma part, tout est des objets en .NET) pour ne jamais être dans un état bizarre et ne pas ralentir inutilement mon thread d'écriture.

Cette solution vous parais viable (et correct ^^) ?
Il existe peut être mieux que sa en .NET (j'utilise le framwork 3.5 ) ?

PS :
J'extrais de ma pile les données par une Fonction (appelé par déléguer, nommé "GetLigneEcrireMethod") qui exécute le verrou ("SyncLoock") extrais une ligne puis déverrouille ma pile donc (sauf erreur de ma part) mon thread principale ne vas devoir attendre l'extraction que d'une donnée de la pile et non la "vidange" complète de la pile (sauf évidement si je n'est rien compris )

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
foliv57 423 Messages postés vendredi 17 novembre 2006Date d'inscription 15 juillet 2014 Dernière intervention - 30 juil. 2010 à 13:07
0
Utile
Voici juste un petit exemple pour illustrer l'appelle d'une sub depuis un thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Thread.CurrentThread.Name = "Mon thread principal"
    Dim th As New Thread(AddressOf Process)
    th.Start()
    MaSub()
End Sub

Private Sub Process()
    Thread.CurrentThread.Name = "Mon thread perso"
    MaSub()
End Sub

Private Sub MaSub()
    Console.WriteLine("{0} dit 'Hello'", Threading.Thread.CurrentThread.Name)
End Sub


Rien ne vaut les exemples ...
Commenter la réponse de foliv57
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 30 juil. 2010 à 15:23
0
Utile
Arf je viens de finir le code en utilisant "IsBackground", donc ce n'est pas la bonne façon de faire (mais sa fonctionne comme je le voulais, même si c'est vrais que du coup mon thread ne se terminais jamais de façon "valide" et ce même si je contrôlais pas trop mal sa fermeture avec ma variable "HaveOne", bon c'est vrais que mon thread fait de temps en temps une boucle dans le vide mais bon sa se resume à un test, dans la réalité je test une 1ére fois le nombre d'élément dans ma pile aven d'ouvrir le stream du fichier, je l'avais supprimer ici pour plus de clarté )

Du coup pour testé j'ai mit en commentaire ma ligne "System.Threading.Thread.CurrentThread.IsBackground = True", et j'ajoute l'interface IDisposable à ma classe.

Une fois cette ligne ajoutée deux fonctions sont automatiquement crée :
Protected Overridable Sub Dispose(ByVal disposing As Boolean)

et
Public Sub Dispose() Implements IDisposable.Dispose


Je place un point d'arrêt sur chacune des 1éres ligne des ces fonctions soit :
If Not Me.disposedValue Then

et
Dispose(True)


Pour finir j'exécute mon code et patatra mon projet ne s'arrête plus et je ne rentre pas dans les fonction ajoutées par l'interface IDisposable, sur la fermeture de ma form (mon projet de test de cette classe est configurer "Shutdown mode : When the startup form closes")

Du coup je réactive ma ligne IsBackground, je relance le projet et pas mieux, ma classe passe bien par le Finalize mais jamais par les fonctions de l'interface IDisposable. Par sécurité j'ai même ajouté Debug.Print("1") et Debug.Print("2") à chacune de procédure et en effet je ne reçois pas ces messages . J'ai du raté quelque chose .

Je test maintenant d'accéder directement au ".Count" et ".Dequeue" sans utilisé de délégué et là sa marche bien (tiens j'étais pourtant certain que j'allais rencontré une exception disant que je ne peut pas accéder à un objet crée par un autre thread ). C'est cool comme sa plus besoin de déclarer tous mes délégués et méthodes (je vais continuer à utilisé les fonctions et procédure que j'ai crée par contre pour continuer à locké mes objets de la même façon, sa me plais bien ).

Merci pour l'exemple mais je sait déjà comment appelé une sub depuis un autre thread (si non je n'en serais pas à cette étape de mon dev ), sa serviras sans doute un jour à quelqu'un qui lira cette discussion

Non, en .Net il y a deux types.
1) Les types valeur (integer, boolean, structure ....)
2) Les types référence (string "et oui... ", Class ....)

Oui je me suis souvenu de sa juste quand j'ai valider mon message (mais je n'est pas voulut re-poster juste pour corrigé sa )

Donc encore un petit pas en avant plus besoin des déléguer (et c'est déjà pas mal, sa y est ma classe commence à me plaire )

Cette classe à pour but d'être commune à pas mal de projet donc des objet seront crée d'un peut toute les façons (dans mon projet de test sa déclaration est "Public Journal As New ClassJournal" dans une form )

PS:
Voila, en espérant que ce roman va vous aider à y voir plus clair.

Oui j'aime les romans (et les exemples évidemment) en générale sa prouve qu'on sait de quoi on parle et/ou qu'on cherche à être le plus précis et claire possible

Dans la série des romans on se fait concurrence en faite

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 30 juil. 2010 à 15:30
0
Utile
Arf j'avais mal lut il faut appelé la fonction dispose depuis l'extérieur de la classe

Heeee bà non, sa me plais pas dans ce cas car une fois ce développement terminé je vais mettre à jour une grosse dizaine de projet qui contienne déjà cette classe (à une autre version mais bon) et je voudrais éviter d'avoir à faire des modifications sur tous ces projets (qui pour certain contienne 5/6 journaux).

J'en reste donc à mon histoire et IsBackground et HaveOne (déjà les délégués vont disparaitre et c'est déjà pas mal )

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 30 juil. 2010 à 17:08
0
Utile
Arf j'ai oublier un petit truc dans ce code posté ci dessus : Le verrouillage de la configuration pendant l'ouverture du fichier (bon mais le principe reste le même donc je ne re-poste pas tout )

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 30 juil. 2010 à 17:59
0
Utile
Aller dernier message sur cette discutions (histoire de vraiment expliqué ce sur je fait )

J'ai fini par remettre une variable StopThreadEcriture. Mais je ne l'utilise pas à la fin de ma classe. Je l'utilise quand mon objet n'est plus référencé (et en prime je mixe un peut les deux façon de faire, mes utilisateurs vont recevoir le version de luxe de ma classe journal )

Dans ma boucle principale (soit la 1ére ligne du code du tred que j'ai posté "while true") je test mes variable2 :
Ma nouvelle ligne
While (Not StopThreadEcriture) Or TickThreadEcritureHaveOne


Qaund je modifie la configuration de mon objet je fait :
StopThreadEcriture = True
TickThreadEcriture.Set()
ThreadEcriture.Join()
'Modification de la configuration
StopThreadEcriture = False
ThreadEcriture = New System.Threading.Thread(AddressOf SubThreadEcriture)
ThreadEcriture.Start()


Voila comme sa plus de problème de configuration, si on veut modifier la configuration il faudra attendre la fin de l'écriture des lignes déjà injecter dans le journal

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 30 juil. 2010 à 18:02
0
Utile
Haaaaaa il commence à être tard
Je l'utilise quand mon objet n'est plus référencé (et en prime je mixe un peut les deux façon de faire, mes utilisateurs vont recevoir le version de luxe de ma classe journal )


Il faut comprendre :
Je l'utilise quand on modifie ma configuration (et en prime je mixe un peut les deux façon de faire, mes utilisateurs vont recevoir le version de luxe de ma classe journal )

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
foliv57 423 Messages postés vendredi 17 novembre 2006Date d'inscription 15 juillet 2014 Dernière intervention - 30 juil. 2010 à 19:25
0
Utile
Je corrige juste une bêtise que j'ai dite pour les courageux qui auraient lu le post en entier.

Utiliser la fonction "Invoke" d'un Delegate ne crée pas un nouveau thread, c'est la fonction "BeginInvoke" qui joue ce rôle. J'ai parlé trop vite. Désolé.

Content que vous soyez arrivé à bout de votre projet Polak77
Commenter la réponse de foliv57

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.