Уничтожение циклических ссылок

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Уничтожение циклических ссылок

Сообщение Antonariy » 02.12.2009 (Ср) 14:12

Обнаружил, что в .NET в этом плане не так все просто как в VB6. Несколько раз перечитал Object Lifetime и так и не понял:

1) Nothing имеет смысл использовать для уничтожения объекта только тогда, когда он не содержит ссылок на другие объекты?
2) Если на объект есть N ссылок, то сначала нужно удалить N-1 с помощью Nothing, а последнюю с помощью Dispose?
3) Имеет ли смысл после obj.Dispose делать obj = Nothing?
4) Что произойдет, если из объекта А вызвать Dispose объекта B, но на него есть ссылка из объекта С?

Есть библиотека классов, в ней класс A, экземпляр которого создает внешнее приложение. Класс A создает экземпляры классов B, C и D, причем А, B и С имеют ссылки друг на друга, на D, а D не имеет никаких ссылок. Для класса D делать Implements IDisposable, я так понимаю, не нужно? Какова должна быть стратегия уничтожения ссылок в данном примере?
Лучший способ понять что-то самому — объяснить это другому.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Уничтожение циклических ссылок

Сообщение Antonariy » 02.12.2009 (Ср) 15:40

Нашел статью, где все красиво разложено по полочкам. Однако примеры там на С#, синтаксис которого я не знаю. Как будут выглятеть на VB указанные комментариями места?

Код: Выделить всё
using System;
using System.Reflection;
using System.Runtime.InteropServices;

namespace RSDN
{
   [AttributeUsage(AttributeTargets.Field)] //
  public class UsingAttribute : Attribute   //
  {                                         //
  }                                         //

public abstract class DisposableType: IDisposable
  {
    bool disposed = false;

    ~DisposableType()    //
    {                    //
      if (!disposed)     //
      {                  //
        disposed = true; //
        Dispose(false);  //
      }                  //
    }                    //

    public void Dispose()
    {
      if (!disposed)
      {
        disposed = true;
        Dispose(true);
        GC.SuppressFinalize(this);
      }
    }

    protected virtual void Dispose(bool disposing)
    {
      DisposeFields(this);
    }

    static public void DisposeFields(object obj) //
    {
      foreach (
        FieldInfo field in
        obj.GetType().GetFields(BindingFlags.Public |
                    BindingFlags.NonPublic |
                    BindingFlags.Instance))
      {
        if (Attribute.IsDefined(field,typeof(UsingAttribute)))  //
        {
          object val = field.GetValue(obj);
          if (val != null)
          {
            if (val is IDisposable)
            {
              ((IDisposable)val).Dispose(); //
            }
            else if (val.GetType().IsCOMObject)
            {
              Marshal.ReleaseComObject(val);
            }
          }
        }
      }
    }
  }
}
Лучший способ понять что-то самому — объяснить это другому.

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Уничтожение циклических ссылок

Сообщение MIT » 02.12.2009 (Ср) 19:15

Расскажу что знаю.

Antonariy писал(а):Если на объект есть N ссылок, то сначала нужно удалить N-1 с помощью Nothing, а последнюю с помощью Dispose?
Если вызвать Dispose у объекта, то все ссылки на него автоматически станут Nothing. Dispose же удаляет не ссылку на объект, а сам объект.
Antonariy писал(а):Имеет ли смысл после obj.Dispose делать obj = Nothing?
Нет, после obj.Dispose obj уже будет равен Nothing
Antonariy писал(а):Что произойдет, если из объекта А вызвать Dispose объекта B, но на него есть ссылка из объекта С?
GC при следующей сборке мусора удалит объект C.

Код: Выделить всё
   [AttributeUsage(AttributeTargets.Field)] //
  public class UsingAttribute : Attribute   //
  {                                         //
  }                                         //
>>
Код: Выделить всё
<AttributeUsage(AttributeTargets.Field)> Public Class UsingAttribute
Inherits Attribute
End Class

static public void DisposeFields(object obj) >> Public Shared Sub DisposeFields(obj as object)
if (Attribute.IsDefined(field,typeof(UsingAttribute))) вроде так же и останется
((IDisposable)val).Dispose(); >> DirectCast(val,IDisposable).Dispose

Что такое ~DisposableType() не знаю :?
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Уничтожение циклических ссылок

Сообщение Antonariy » 03.12.2009 (Чт) 11:37

GC при следующей сборке мусора удалит объект C.
Почему? Из ответа на первый вопрос следует, что ссылка из объекта C станет nothing, а с самим объектом ничего не случится. Подразумевается, что на С из A тоже есть ссылка.
вроде так же и останется
Говорит 'UsingAttribute' is a type and cannot be used as an expression.
Все остальное правильно, спасибо.
Лучший способ понять что-то самому — объяснить это другому.

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Уничтожение циклических ссылок

Сообщение MIT » 03.12.2009 (Чт) 11:55

Antonariy писал(а):Почему?
Да не почему, а из-за чего. Из-за невнимательности :) . Что-то я сначала понял задачу как иерархическую: у А есть ссылка на В, у В есть ссылка на С, а оказывается оно и не так.
Перечитал.
После того, как у объекта В будет вызвана процедура Dispose, то все ссылки на него (и из объекта А и из С) станут Nothing, объекта В уже не будет существовать.

Antonariy писал(а):Говорит 'UsingAttribute' is a type and cannot be used as an expression.
Тогда может так: if (Attribute.IsDefined(field,UsingAttribute))?
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Уничтожение циклических ссылок

Сообщение ANDLL » 03.12.2009 (Чт) 12:30

Если вызвать Dispose у объекта, то все ссылки на него автоматически станут Nothing. Dispose же удаляет не ссылку на объект, а сам объект.
Это не так. Если вызвать Dispose ни одна из ссылок(даже так для который был вызыван Dispose) не изменит значения.
Нет, после obj.Dispose obj уже будет равен Nothing
Не будет
1) Nothing имеет смысл использовать для уничтожения объекта только тогда, когда он не содержит ссылок на другие объекты?
2) Если на объект есть N ссылок, то сначала нужно удалить N-1 с помощью Nothing, а последнюю с помощью Dispose?
3) Имеет ли смысл после obj.Dispose делать obj = Nothing?
4) Что произойдет, если из объекта А вызвать Dispose объекта B, но на него есть ссылка из объекта С?

Ответим двумя фактами.
А) В .NET не существует способа удаления объектов.
Б) Метод Dispose() это просто метод. Он не играет совсем никакой(совсем совсем никакой) роли в работе GC.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Уничтожение циклических ссылок

Сообщение MIT » 03.12.2009 (Чт) 12:54

ANDLL писал(а):Это не так
ANDLL писал(а):Не будет
!!!!! :|
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Уничтожение циклических ссылок

Сообщение Antonariy » 03.12.2009 (Чт) 17:52

Подсказали мастхэвный переводчик с C# на VB.
http://www.developerfusion.com/tools/co ... arp-to-vb/
Лучший способ понять что-то самому — объяснить это другому.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Уничтожение циклических ссылок

Сообщение ANDLL » 03.12.2009 (Чт) 19:09

Подсказали или таки погуглили?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Уничтожение циклических ссылок

Сообщение Antonariy » 04.12.2009 (Пт) 11:07

Подсказали.
Лучший способ понять что-то самому — объяснить это другому.


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 54

    TopList