|
-
Jul 9th, 2009, 11:57 AM
#1
Thread Starter
New Member
RaiseEvent issue
Hello,
I use the RaiseEvent method to indicate to some classes to clear their memory (setting members to nothing so the garbage collector can do its job).
I call it in the FormClosing event of a form, but, for some reasons the process won't continue after the RaiseEvent line:
Code:
Private Sub FormHorodateur_FormClosing(ByVal sender As Object, _
ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
m_grid = Nothing
RaiseEvent OnNotification(New Notification(EnumNotificationType.DOCUMENT_CLOSING, Me.GetType.Name, Me.GetType.Name, Me.GetType()))
Me.Dispose()
End Sub
... and the form never closes. Do you have any idea ?
Thank you,
Loïc Bauduin Brunelle,
ing jr.
-
Jul 9th, 2009, 12:41 PM
#2
Thread Starter
New Member
Re: RaiseEvent issue
I've partially resolved my problem. There was a missing "RemoveHandler". But, there is still something strange: the first time I try to close my window, the RaiseEvent does not come back to its calling point, but the second time I hit the "X" button, the RaiseEvent works perfectly...
-
Jul 9th, 2009, 01:13 PM
#3
Re: RaiseEvent issue
Just a guess here, try removing Me.Dispose() from your code and see what happens.
Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
- Abraham Lincoln -
-
Jul 9th, 2009, 05:20 PM
#4
Thread Starter
New Member
Re: RaiseEvent issue
In fact, the first time it enters the FormClosing event, My.Dispose is not even executed. The track is lost in the first call to RaiseEvent (I set a breakpoint on My.Dispose and it only breaks the second time I tried to close my window).
-
Jul 9th, 2009, 08:01 PM
#5
Re: RaiseEvent issue
You absolutely should not be calling Dispose in the FormClosing event handler. The reason the FormClosing event is raised is because the form is closing and closing a form disposes it. The FormClosing event is raised, the form is disposed and then the FormClosed event is raised.
This assumes that the form was displayed by calling Show. If it was displayed by calling ShowDialog then closing it does not dispose, but there's still no reason for you to explicitly call Dispose in the FormClosing event handler. In that case it is the resposibility of the code that called ShowDialog to dispose the form, which it should usually do with a Using block.
-
Jul 13th, 2009, 11:34 AM
#6
Thread Starter
New Member
Re: RaiseEvent issue
Ok thank you, I removed the call to Dispose... but I still have my problem: the first time I hit the "X" button, my form does not close!
-
Jul 13th, 2009, 12:12 PM
#7
Re: RaiseEvent issue
Can you post your current code (including what is in the event handler that is executed from your OnNotification event) ?
-
Jul 14th, 2009, 11:26 AM
#8
Thread Starter
New Member
Re: RaiseEvent issue
Here's my sender:
Code:
Public Class GestionnaireNotification
' Cette classe n'est pas un gestionnaire proprement dit...
' elle ne sert qu'à dispatcher les notifications
Sub Diffuser(ByVal _notification As Notification)
RaiseEvent SurNotification(_notification)
End Sub
Delegate Sub SurNotif(ByVal _notification As Notification)
Public Event SurNotification As SurNotif
End Class
'=========================================================
#Region "Notifications"
Private m_gestionnaireNotification As GestionnaireNotification
Public ReadOnly Property GesNotif() As GestionnaireNotification
Get
If m_gestionnaireNotification Is Nothing Then
m_gestionnaireNotification = New GestionnaireNotification()
End If
Return m_gestionnaireNotification
End Get
End Property
#End Region
'=========================================================
Public ReadOnly Property DocHoro() As DocumentHorodateur
Get
If m_documentHorodateur Is Nothing Then
m_documentHorodateur = New DocumentHorodateur()
m_documentHorodateur.Ouvrir()
End If
Return m_documentHorodateur
End Get
End Property
Public Sub FermerDocHoro()
m_documentHorodateur.Fermer()
m_documentHorodateur = Nothing
End Sub
And here is how I use the sender:
Code:
Public Class DocumentHorodateur
Inherits Document
Private m_CompagnieActive As CompagnieHorodateur
Private m_TypeCalendrierActif As CalendrierType
...
Public Overrides Sub Fermer()
m_CompagnieActive = Nothing
m_TypeCalendrierActif = Nothing
MyBase.Fermer()
End Sub
End Class
'=========================================================
Public MustInherit Class Document
Implements IDocument
' Variables membres
Protected m_tabGestionnaire As Hashtable
Protected m_tabSousDocument As ArrayList
...
Public Overridable Sub Fermer() Implements IDocument.Fermer
' Envoyer une notification comme quoi on ferme le document
RemoveHandler GesNotif.SurNotification, AddressOf SurNotification
GesNotif.Diffuser(New Notification(EnumNotificationType.FERMETURE_DOCUMENT, Me.GetType.Name, Me.GetType.Name, Me.GetType()))
m_tabGestionnaire = Nothing
m_tabSousDocument = Nothing
' Éventuellement, il faudrait vérifier s'il y a des objets à sauvegarder ...
End Sub
...
End Class
'=========================================================
Private Sub FormHorodateur_FormClosing(ByVal sender As Object, _
ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
' Tester si on peut fermer la fenêtre
Dim ob As Form = Application.OpenForms(GetType(FormCompagnieHorodateur).Name)
If ob IsNot Nothing Then
e.Cancel = True
Exit Sub
End If
RemoveHandler GesNotif.SurNotification, AddressOf SurNotification
m_grid = Nothing
FermerDocHoro()
End Sub
I got a lot of handlers... I can show you some of them (they follow the same "rules"):
Code:
Public MustInherit Class Document
Implements IDocument
' Variables membres
Protected m_tabGestionnaire As Hashtable
Protected m_tabSousDocument As ArrayList
Sub New()
m_tabGestionnaire = New Hashtable
m_tabSousDocument = New ArrayList
AddHandler GesNotif.SurNotification, AddressOf SurNotification
End Sub
...
Public Overridable Sub SurNotification(ByVal _notification As Notification) Implements IDocument.SurNotification
' Si c'est une fermeture de document, vérifier dans les sous-documents si une référence est gardée
If _notification.NotificationType = EnumNotificationType.FERMETURE_DOCUMENT Then
For Each doc As Object In m_tabSousDocument
If doc.GetType.Name = _notification.ObjetCle Then
m_tabSousDocument.Remove(doc)
End If
Next
End If
End Sub
End Class
'=========================================================
Public MustInherit Class GestionnaireObjet
Implements IGestionnaireObjet
' Variables membres
Private m_dernierIdTmp As Long
Protected m_document As IDocument
Protected m_tabObjet As ArrayList
Protected m_typeObjet As Type
Protected m_typeTri As EnumTriType
' Constructeur
Sub New()
m_dernierIdTmp = -1
m_tabObjet = New ArrayList
m_typeTri = EnumTriType.NULL
AddHandler GesNotif.SurNotification, AddressOf SurNotification
End Sub
...
Public Overridable Sub SurNotification(ByVal _notification As Notification) Implements IGestionnaireObjet.SurNotification
If _notification.ObjetType Is Document.GetType AndAlso _
_notification.NotificationType = EnumNotificationType.FERMETURE_DOCUMENT Then
For Each ob As Objet In m_tabObjet
ob.MettreANothing()
Next
m_tabObjet = Nothing
Document = Nothing
RemoveHandler GesNotif.SurNotification, AddressOf SurNotification
End If
End Sub
End Class
'=========================================================
Public Class FormHorodateur
Private m_grid As ControleurDeGrid
Sub New()
' Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()
' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
' Initialisation du Grid
m_grid = New ControleurDeGrid(Me.Grid, False)
...
' Écouter les notifications pour mettre à jour les objets affichés
AddHandler GesNotif.SurNotification, AddressOf SurNotification
'CType(DocGen().RetournerGestionnaire(GetType(Texte)), GestionnaireTexte).InitialiserFenetre(Me)
End Sub
...
Private Sub SurNotification(ByVal _notification As Notification)
' On ne met à jour la fenêtre que s'il y a une modification BD ou qu'un objet est supprimé
' on ne met pas l'événement POST_SUPPRIME_DANS_BD parce que l'objet est encore en mémoire à ce moment
If _notification.NotificationType <> EnumNotificationType.SUPPRIME AndAlso _
_notification.NotificationType <> EnumNotificationType.POST_TELEVERSE_DANS_BD Then
Exit Sub
End If
' Le type d'objet doit être CompagnieHorodateur, ou personne horodateur si on affiche les employés
Select Case _notification.ObjetType.Name
Case GetType(CompagnieHorodateur).Name
MiseAJourGrid()
Case GetType(PersonneHorodateur).Name
MiseAJourListe(m_grid.CelluleSelectionnee)
End Select
End Sub
End Class
-
Jul 17th, 2009, 06:34 AM
#9
Thread Starter
New Member
Re: RaiseEvent issue
I finaly found my problem: it was only an exception in one of my handlers. I'm still not used to those try/catch!
I guess this thread could be set to Resolved now.
-
Jul 17th, 2009, 07:13 AM
#10
Re: RaiseEvent issue
If you use a Try/Catch block, you must always at least do something in the Catch block. At least put a Debug.Writeline there, or maybe even a messagebox, informing you of the error. If you're going to use Try/Catch without any error messages, you are going to miss errors and leave everyone wondering what the hell went wrong.
Also, you need to set your thread to resolved yourself. Just click on 'Mark Resolved' in the Thread Tools menu at the top.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|