Pregunta

Esporádicamente recibimos errores cuando intentamos actualizar una información sobre herramientas, como esta

ToolTip.SetToolTip(myLabel, customDataStructure)

El error que obtenemos es una NullReferenceException: referencia de objeto no establecida en una instancia de un objeto

¿Alguien sabe la causa de esto?

¿Es un Try / Catch simple que se come la NullReferenceException una opción viable? No queremos que toda nuestra aplicación explote cuando recibamos esto.

¿Fue útil?

Solución

Supongo que está llamando a ToolTip.SetTooltip desde un controlador de eventos y ese controlador a veces se activa antes de que se haya creado la etiqueta. Probablemente debería guardar esto con una verificación de que la etiqueta sea null y luego asegurarse de que la información sobre herramientas se inicie en el evento Load de la etiqueta.

Desde luego, no solo deberías detectar la excepción, ya que esto oculta el problema.

Otros consejos

Rechazar las excepciones rara vez es una buena idea. Se produce la excepción porque algo está mal en la implementación actual. Al ignorar la excepción, la aplicación básicamente continúa en un estado indefinido y lo más probable es que vea otros efectos extraños debido a la referencia faltante.

Dado que esto es esporádico, podría tratarse de un problema de condición de carrera, por lo que debe observar detenidamente el código para determinar si hay alguna situación en la que se pueda usar la referencia antes de que se inicialice correctamente.

Intente probar si está configurando esa var en cualquier situación, utilizando el depurador, por ejemplo ...

¿Es una opción viable un Try / Catch simple que se come la NullReferenceException?

Eso no resolvería el problema, lo escondería. Una mala práctica de programación.

La causa más común de esto es cuando cierras una ventana y se produce una validación que establece una información sobre herramientas en un control invisible.

No he depurado en el código .Net pero tengo una idea bastante buena de dónde se produce el error en el código de 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 condición para solucionar este problema es muy simple, simplemente verifique si el formulario está visible o como lo menciona Benjamin RAIBAUD Desechado = falso antes de llamar al método SetToolTip de ToolTip:

C #:

if (!this.Disposing) ttpHoverText.SetToolTip(targetControl, brokenText);

VB.Net:

If Me.Disposing = False Then ttpHoverText.SetToolTip(targetControl, brokenText)
  

OMI Esto es algo que debe ser manejado por .Net Framework ...

Me acabo de encontrar con el mismo problema. Parece que la excepción se produce desde el método ToolTip.CreateHandle () y sucede en la ventana secundaria MDI que solo se desecha. Antes de llamar al método SetToolTip (...), asegúrese de que la propiedad Disposing del formulario padre sea falsa. De todos modos, el formulario se está eliminando, por lo que ya no te importa la información sobre herramientas ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top