Исключение NullReferenceException с всплывающей подсказкой.CreateHandle

StackOverflow https://stackoverflow.com/questions/826652

Вопрос

Время от времени мы получаем ошибки при попытке обновить всплывающую подсказку, например, так

ToolTip.SetToolTip(myLabel, customDataStructure)

Ошибка, которую мы получаем, - это NullReferenceException: Object reference not set to an instance of an object

Кто-нибудь знает причину этого?

Является простым Try/Catch который съедает NullReferenceException выполнимый вариант?Мы не хотим, чтобы все наше приложение взорвалось, когда мы получим это.

Это было полезно?

Решение

Я бы предположил, что ты звонишь ToolTip.SetTooltip из обработчика событий, и этот обработчик иногда срабатывает до того, как метка была создана.Вероятно, вам следует защитить это проверкой на наличие метки null а затем убедитесь, что подсказка инициализирована на этикетке Load событие.

Вы, конечно, не должны просто перехватывать исключение, поскольку это скрывает проблему.

Другие советы

Игнорирование исключений редко, если вообще когда-либо, является хорошей идеей.Исключение выдается из-за того, что что-то не так в текущей реализации.Игнорируя исключение, приложение в основном переходит в неопределенное состояние, и вы, скорее всего, увидите другие странные эффекты из-за отсутствия ссылки.

Поскольку это происходит спорадически, это может быть проблема с состоянием гонки, поэтому вы должны внимательно изучить код, чтобы выяснить, есть ли какие-либо ситуации, в которых ссылка может быть использована до ее правильной инициализации.

Попробуйте проверить, устанавливаете ли вы этот параметр в любой ситуации, например, используя отладчик...

Является ли простая попытка / перехват, которая использует исключение NullReferenceException, выполнимым вариантом?

Это не решило бы проблему, а скрыло бы ее.Плохая практика программирования.

Наиболее распространенной причиной этого является то, что вы закрываете окно и происходит проверка, которая устанавливает всплывающую подсказку для невидимого элемента управления.

Я не проводил отладку в коде .Net, но у меня есть довольно хорошая идея, где во всплывающей подсказке выдается ошибка.Код 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));
    }

Условие для исправления этого очень простое, просто проверьте, видна ли форма или, как упоминает Бенджамин РАЙБО, Disposing = false перед вызовом метода управления всплывающей подсказкой SetToolTip:

C#:

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

VB.Net:

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

IMO, это то, что должно обрабатываться .Net Framework...

Я только что столкнулся с той же проблемой.Кажется, что исключение генерируется из метода ToolTip.CreateHandle(), и это происходит только при удалении дочернего окна MDI.Перед вызовом метода SetToolTip(...) убедитесь, что удаляющее свойство родительской формы равно false.В любом случае, форма утилизируется, так что на самом деле всплывающие подсказки вас больше не волнуют...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top