Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
5 / 5 / 1
Регистрация: 26.10.2010
Сообщений: 126

Намекнуть GarbageCollector, что ресурс я удалю сам или можно его удалять только после выполнения деструктора

22.12.2011, 20:07. Показов 1524. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток, форумчане!

Возникла проблема с последовательностью выполнения деструкторов у объекта класса.
В деструкторе класса необходимо выполнить ряд действий связанный с использованием членов этого класса (UdpSocket, System.Timers.Timer). Но к моменту вызова этого самого деструктора сборщиком мусора сокет уже закрыт, а таймер прибит. В настоящий момент я просто написал заплатку в виде локального сокета и такого же таймера. Но хотелось бы сделать по человечески...

Отсюда вопрос: как намекнуть GarbageCollector, что ресурс я удалю сам или можно его удалять только после выполнения деструктора?

GC.KeepAlive - не тот случай, GC.SuppressFinalize, вызванный ещё при конструировании - не помогает.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.12.2011, 20:07
Ответы с готовыми решениями:

Ребята Можно и похожую скинуть, что бы сам сделал или ссылкой на ресурс, где понятно показано, как делать
1. Создать базу данных «Соревнования», включающую сведения о соревнованиях по какому-либо виду спорта. 2. Продумать состав и структуру...

Каталог в ресурс или что можно придумать
Всем доброго времени суток. Друзья, мне нужно создать папку с общим доступом и что бы у всех были права не только на чтение но и на...

Можно ли удалять одинаковый софт только разного года (оставлять тот что поновее) ?
можно ли удалять одинаковый софт только разного года (оставлять тот что поновее) например: у меня net fraemwork 4.5 / 4.5.1. / 4.6 и т.д.

11
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
22.12.2011, 23:19
Цитата Сообщение от silicium Посмотреть сообщение
как намекнуть GarbageCollector, что ресурс я удалю сам
Простите, как? В CLR удалением объектов занимается именно GC, у пользователя такой возможности нет.

Цитата Сообщение от silicium Посмотреть сообщение
или можно его удалять только после выполнения деструктора?
Так деструктор вызывается как раз перед удалением.
То есть память, используемая объектом, всегда освобождается после выполнения деструктора.

Цитата Сообщение от silicium Посмотреть сообщение
В деструкторе класса необходимо выполнить ряд действий связанный с использованием членов этого класса (UdpSocket, System.Timers.Timer). Но к моменту вызова этого самого деструктора сборщиком мусора сокет уже закрыт, а таймер прибит.
Так добавьте проверку в деструкторе:
C#
1
2
if (timer != null) timer.Dispose();
if (socket != null) socket.Dispose();
Кстати, если ваш класс использует объекты классов, реализующих IDisposable, то он сам должен его реализовать. Это не правило, компилятор ругаться не будет, но очень хорошая и полезная практика.

Полностью паттерн при этом выглядит так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyClass : IDisposable
{
   Socket socket;
   Timer timer;
 
   ~MyClass()
   {
      this.Dispose();
   }
   public void Dispose()
   {
      if (socket != null) socket.Dispose();
      if (timer != null) timer.Dispose();
   }
}
0
5 / 5 / 1
Регистрация: 26.10.2010
Сообщений: 126
22.12.2011, 23:53  [ТС]
Проблема в том, что в момент вызова деструктора, сокет уже закрыт, а не в том, чтобы его удалить. А сокет нужен открытым для правильного выполнения деструктора.

Добавлено через 1 минуту
А насчёт хорошего тона относительно использования интерфейса IDisposable - полностью согласен
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
22.12.2011, 23:55
Цитата Сообщение от silicium Посмотреть сообщение
А сокет нужен открытым для правильного выполнения деструктора.
Эм... Ну так не закрывайте его до вызова деструктора, в чем проблема? Ну или сделайте проверку: если не закрыт, то закрыть, если закрыт - замечательно, можно идти спать.

Или я чего-то не понимаю?
0
Кодило
 Аватар для r0fL
251 / 179 / 23
Регистрация: 25.11.2009
Сообщений: 685
23.12.2011, 00:37
kolorotur, я так понимаю, что проблема в том, что при вызове GC он сначала закрывает сокет и таймер, а потом вызывает деструктор, в котором нужны как раз сокет и таймер.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
23.12.2011, 01:49
Цитата Сообщение от r0fL Посмотреть сообщение
я так понимаю, что проблема в том, что при вызове GC он сначала закрывает сокет и таймер, а потом вызывает деструктор, в котором нужны как раз сокет и таймер.
Если внутри вашего класса сокет и таймер не выходят из области видимости до запуска деструктора, то сборщик их трогать не будет. В особенности таймер, который вообще не будет уничтожен до тех пор, пока на нем не будет вызван метод Dispose.
0
72 / 17 / 2
Регистрация: 29.12.2010
Сообщений: 339
23.12.2011, 03:58
По моим сведениям можно было отключить GarbageCollector и всё dispose вручную
0
5 / 5 / 1
Регистрация: 26.10.2010
Сообщений: 126
23.12.2011, 10:57  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Если внутри вашего класса сокет и таймер не выходят из области видимости до запуска деструктора, то сборщик их трогать не будет.
А вот оказывается, что будет:
Так удаляется объект: сначала удаляются все его переменные, потом вызывается его деструктор, потом переходим к базовому классу


Цитата Сообщение от Смирняга Посмотреть сообщение
По моим сведениям можно было отключить GarbageCollector и всё dispose вручную
т.е. если Dispose не вызван - всё, объект болтается в памяти до закрытия программы?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
23.12.2011, 16:48
Цитата Сообщение от Смирняга Посмотреть сообщение
По моим сведениям можно было отключить GarbageCollector и всё dispose вручную
Нельзя. Во-первых, не все классы реализуют IDisposable, во-вторых, реализация этого интерфейса существует для того, чтобы освободить неуправляемые ресурсы. Управляемые все равно должен освободить сборщик.

Цитата Сообщение от silicium Посмотреть сообщение
Так удаляется объект: сначала удаляются все его переменные, потом вызывается его деструктор, потом переходим к базовому классу
Не совсем. Переменные объекта не удаляются, просто сначала для каждой из них вызывается деструктор, если он определен. Но память, занимаемая этими объектами, будет возвращена операционной системе только после уничтожения "родительского" объекта. То есть на момент вызова деструктора основного класса, его переменные еще живы (но могут быть уже диспознуты, что может предотвратить использование их методов/свойств).

Цитата Сообщение от silicium Посмотреть сообщение
т.е. если Dispose не вызван - всё, объект болтается в памяти до закрытия программы?
Не всегда, но с некоторыми классами - да, такое возможно. Например, с таймерами.
0
5 / 5 / 1
Регистрация: 26.10.2010
Сообщений: 126
24.12.2011, 10:16  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
на момент вызова деструктора основного класса, его переменные еще живы (но могут быть уже диспознуты, что может предотвратить использование их методов/свойств)
именно так по сути и происходит. Можно этого как-либо избежать?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
24.12.2011, 16:59
Цитата Сообщение от silicium Посмотреть сообщение
именно так по сути и происходит. Можно этого как-либо избежать?
Исходя из личного опыта могу сказать, что если потребовались подобные огороды, то для начала стоит пересмотреть проблему - скорее всего этого можно избежать.
Что именно вы пытаетесь сделать с таймером и сокетом в деструкторе вашего класса? Для чего вам нужно, чтобы они на этот момент были не уничтожены?
0
5 / 5 / 1
Регистрация: 26.10.2010
Сообщений: 126
24.12.2011, 17:43  [ТС]
Собственно, проблемы то я уже избежал: написал небольшую заплатку, повторяющую код класса, но на локальных переменных: таймере и сокете.

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

Вот и кажется мне, что некрасиво писать отдельный код и грузить комп повторением действий
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.12.2011, 17:43
Помогаю со студенческими работами здесь

[Gentoo] Иксы: что с ними делать? удалять или можно еще наладить?
Доброго времени суток. Перестали запускаться иксы, после установки графического терминала. долго уже мучаюсь с этими иксами и подумал,...

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

Два класса, два деструктора. После срабатывания второго первому нечего удалять
Доброго времени суток. Помогите, пожалуйста, понять где ошибка. Компилируется, вылетает на деструкторе класса one. Либо что-то не...

Что можно делать с FTP если открыт анонимный доступ? Как удалять или заливать на него файлы ?
подробнее если можно

группа или ресурс не находятся в нужном состании для выполнения требуемой опирации
доброго времени суток! такая вот проблема возникла 2-3 назад, пытаюсь создать точку доступа Wi-fi, но выдается такая вот ошибка ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 30.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru