NullReferenceException con ToolTip.CreateHandle
-
05-07-2019 - |
Domanda
Otteniamo sporadicamente errori quando proviamo ad aggiornare un suggerimento, come questo
ToolTip.SetToolTip(myLabel, customDataStructure)
L'errore che riceviamo è un NullReferenceException: riferimento all'oggetto non impostato su un'istanza di un oggetto
Qualcuno ne conosce la causa?
Un semplice Try / Catch
che mangia il NullReferenceException
è un'opzione fattibile? Non vogliamo che la nostra intera applicazione esploda quando otteniamo questo.
Soluzione
Immagino che tu stia chiamando ToolTip.SetTooltip
da un gestore di eventi e quel gestore a volte si attiva prima che l'etichetta sia stata creata. Probabilmente dovresti proteggerlo con un controllo per l'etichetta null
e quindi assicurarti che la descrizione comandi sia inizializzata sull'evento Load
dell'etichetta.
Non dovresti certo cogliere l'eccezione perché questo nasconde il problema.
Altri suggerimenti
Ignorare le eccezioni è raramente una buona idea. L'eccezione viene generata perché nell'attuale implementazione c'è qualcosa che non va. Ignorando l'eccezione, l'applicazione procede sostanzialmente in uno stato indefinito e molto probabilmente vedrai altri strani effetti dovuti al riferimento mancante.
Poiché questo è sporadico, potrebbe trattarsi di un problema relativo alle condizioni della competizione, quindi è necessario esaminare attentamente il codice per capire se ci sono situazioni in cui il riferimento può essere utilizzato prima che venga inizializzato correttamente.
Prova a verificare se stai impostando quel var in qualsiasi situazione, usando ad esempio il debugger ...
È un semplice Try / Catch che mangia NullReferenceException un'opzione fattibile?
Ciò non risolverebbe il problema, lo nasconderebbe. Una cattiva pratica di programmazione.
La causa più comune di ciò è quando si chiude una finestra e si verifica la convalida che imposta una descrizione comandi su un controllo invisibile.
Non ho eseguito il debug nel codice .Net ma ho una buona idea di dove viene generato l'errore nel codice ToolTip.CreateHandle:
private void CreateHandle()
{
if (this.GetHandleCreated())
{
return;
}
IntPtr userCookie = UnsafeNativeMethods.ThemingScope.Activate();
try
{
SafeNativeMethods.InitCommonControlsEx(new NativeMethods.INITCOMMONCONTROLSEX
{
dwICC = 8
});
CreateParams createParams = this.CreateParams;
if (this.GetHandleCreated())
{
return;
}
//HERE! I suspect window is null when the form is closed
this.window.CreateHandle(createParams);
}
finally
{
UnsafeNativeMethods.ThemingScope.Deactivate(userCookie);
}
if (this.ownerDraw)
{
int num = (int)((long)UnsafeNativeMethods.GetWindowLong(new HandleRef(this, this.Handle), -16));
num &= -8388609;
UnsafeNativeMethods.SetWindowLong(new HandleRef(this, this.Handle), -16, new HandleRef(null, (IntPtr)num));
}
La condizione per risolvere questo problema è molto semplice, basta controllare se il modulo è visibile o come Benjamin RAIBAUD menziona Disposing = false prima di chiamare i controlli ToolTip Metodo SetToolTip:
C #:
if (!this.Disposing) ttpHoverText.SetToolTip(targetControl, brokenText);
VB.Net:
If Me.Disposing = False Then ttpHoverText.SetToolTip(targetControl, brokenText)
IMO Questo è qualcosa che dovrebbe essere gestito da .Net Framework ...
Ho appena riscontrato lo stesso problema. Sembra che l'eccezione venga generata dal metodo ToolTip.CreateHandle () e si verifica solo nella finestra figlio MDI che viene eliminata. Prima di chiamare il metodo SetToolTip (...), assicurarsi che la proprietà Disposing del modulo padre sia falsa. Ad ogni modo, il modulo è in fase di eliminazione, quindi non ti preoccupi più delle descrizioni comandi ...