2012-03-26 2 views
0

Мне любопытно узнать, возможно ли, что в приведенном ниже коде статический экземпляр не равен null, но ссылка на класс MYDB будет удалена GAC и установлена ​​в значение null?Вопросы со ссылкой на объекты со статическими экземплярами

public class DA_Setting 
{ 
    private static readonly DA_Setting instance = new DA_Setting(); 

    public static DA_Setting Instance 
    { 
     get { return instance; } 
    } 

    db MYDB = new db(); 

    // Some other methods here 

    private void Getname() 
    { 
     MYDB.GetNames(); // Sometimes this line throws null reference error on LIVE server. 
    } 
} 
+0

instance.MYDB.GetNames()? – Goran

+0

его создание вызова БД. –

+2

Посмотрите (или покажите нам) стопку исключения. – Heinzi

ответ

3

GC никогда не будет устанавливать когда-либоnull. Период.

Если у вас есть ссылка на объект, GC предназначен для того, чтобы увидеть, что вы все еще используете объект, удерживая его по этой ссылке, и, следовательно, не будете собирать его, пока не закончите с ним ,

Единственный способ для MYDB поля, чтобы быть null, если вы не присвоить ему значение (и я могу видеть, у вас есть инициализатор в вашем коде, который предотвращает этот сценарий), или если присвоить значение null к полю в какой-то более поздней точке вашего кода.

Я хотел бы предложить вам превратить MYDB в собственность ПОЛУЧИТЬ только и инициализировать его в конструкторе класса:

private DA_Setting() 
{ 
    this.MYDB = new db(); 
} 

public db MYDB { get; private set; } 

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

+0

Спасибо за вашу помощь! –

+0

Если это помогает решить вашу проблему, пожалуйста, отметьте как «принятый» ответ на ваш вопрос. Если нет, обновите свой вопрос с дополнительной информацией, и мы можем попытаться помочь вам дальше. –

+0

Утверждение, что «GC никогда, никогда не установит что-то нулевое», фактически неверно. Обычно он рассчитывает проверить факты, прежде чем делать категорические заявления. Свойство 'Target' класса http://msdn.microsoft.com/en-us/library/system.weakreference.aspx WeakReference * может быть * установлено на' null' во время GC. –

1

GC не собирает это поле, если оно еще доступно, и оно достижимо. Я предполагаю, что другой объект имеет значение null. Вы пытались войти в код, возможно, в методе GetNames?

Ваша статическая переменная является GC Root, это означает, что она не будет получена до тех пор, пока запущено приложение Application/AppDomain. Поле является полем корня GC, поэтому не должно быть никакого способа его сбора. См. Здесь для получения дополнительной информации о сборе мусора: http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/

+0

вы в этом уверены? –

+0

Да, было бы очень плохо, если бы GC просто украл ваши переменные во время работы вашей программы, не так ли? Я уверен, что ошибка нулевой ссылки находится где-то в другом месте, вполне возможно, внутри метода GetNames. Попробуйте войти в нее. Или посмотрите на трассировку стека, которая поставляется с исключением. – Botz3000

+0

Спасибо за помощь! –

1

Это не должно произойти, как я понимаю. Статические инициализаторы и конструкторы запускаются перед доступом к статическому члену - это обещано документацией на C#. Инициализаторы экземпляра запускаются с помощью конструктора экземпляра, поэтому, если вы вызываете DA_Setting.Instance.Getname(), там никогда не должно быть нулевой ссылки. Сборщик мусора не собирается случайно приходить и распоряжаться тем, на что у вас есть ссылка, и у вас определенно все еще есть ссылка на это, поскольку статические члены не имеют конца жизненного цикла, пока приложение по-прежнему Бег.

Вы проверили, что это такое, вызвавшее исключение нулевой ссылки? Может ли это быть внутри экземпляра db?

+0

Хорошо, что трассировка журнала в позиции, показывает, что ссылка на объект равна нулю. Поскольку вы все говорите, что GC не будет удалять ссылки, которые статический экземпляр класса удерживает, то моим следующим шагом было бы запустить sql-профилировщик на моем LIVE-сервере и проверьте возвращаемый параметр и значение. –

Смежные вопросы