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.

È stato utile?

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 ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top