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
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
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
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é)
While MyControl.Invoke(GetCountPileAEcrireMethod) > 0 Try MyStreamWriter.WriteLine(MyControl.Invoke(GetLigneEcrireMethod))
Donc voila tout (pour le moment) sauf que je crains une erreur (perdre la dernière ligne de mon journal)
(enfin objet vue que, sauf erreur de ma part, tout est des objets en .NET)
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
Il existe peut être mieux que sa en .NET (j'utilise le framwork 3.5 ) ?
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()
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
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
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
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
Dim stoped As Boolean = ThreadEcriture.Join(30000) If Not stoped Then ThreadEcriture.Abort() '+ Génération d'une erreur
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
While Not StopThreadEcriture() TickThreadEcriture.WaitOne() 'Ici j'écris dans mon fichier temps que ma pile n'est pas vide End While
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionPrivate MonThreadEcriture = System.Threading.Thread Private TickThreadEcriture As New System.Threading.AutoResetEvent(False)
MonThreadEcriture = New System.Threading.Thread(AddressOf SubThreadEcriture) MonThreadEcriture.Start()
MonThreadEcriture.IsBackground = False 'Ajout d'une ligne dans ma pile TickThreadEcriture.Set
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
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
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
Public Sub Dispose() Implements IDisposable.Dispose
If Not Me.disposedValue Then
Dispose(True)
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 ....)
Voila, en espérant que ce roman va vous aider à y voir plus clair.
While (Not StopThreadEcriture) Or TickThreadEcritureHaveOne
StopThreadEcriture = True TickThreadEcriture.Set() ThreadEcriture.Join() 'Modification de la configuration StopThreadEcriture = False ThreadEcriture = New System.Threading.Thread(AddressOf SubThreadEcriture) ThreadEcriture.Start()
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 )