powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / CA2000: Dispose objects before losing scope
15 сообщений из 15, страница 1 из 1
CA2000: Dispose objects before losing scope
    #38251137
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот есть такое предупреждение о работе с диспосабл обьектами:

http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(CA2000);k(TargetFrameworkMoniker-.NETFramework,Version=v4.0);k(DevLang-csharp)&rd=true


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
public SerialPort OpenPort2(string portName)
{
   SerialPort tempPort = null;
   SerialPort port = null;
   try
   {
      tempPort = new SerialPort(portName);
      tempPort.Open();
      SomeMethod();
      //Add any other methods above this line
      port = tempPort;
      tempPort = null;

   }
   finally
   {
      if (tempPort != null)
      {
         tempPort.Close();
      }
   }
   return port;
}



т.е. предлагают любой такой обьект вручную обнулять, а то в случае возникновения исключения обьект никогда не будет собран сборщиком мусора. Почему так произойдет? Почему сборщик мусора не сможет его собрать? Например надо-ли например DataSet таким образом обнулять после каждого использования?
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38251144
WPF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если ссылка остается, как например с хендлерами, сборщик проходит мимо. Совет, уничтожайте инстанс класса.
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38251145
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
это речь идет об unmanaged ресурсах, типа файлов, верно? А стандартные дотнетовские классы, типа датасетов будут уничтожены и так?
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38251404
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenfordт.е. предлагают любой такой обьект вручную обнулять, а то в случае возникновения исключения обьект никогда не будет собран сборщиком мусора.
Там сказано что "an exceptional event might occur that will prevent the finalizer of the object from running". То есть finalizer может не выполниться.

stenfordПочему сборщик мусора не сможет его собрать?
Всё он сможет, не волнуйся. При условии что на этот объект нет ссылок.

stenfordНапример надо-ли например DataSet таким образом обнулять после каждого использования?
Не нужно т.к. метод Dispose в DataSet ничего не делает и присутствует в нем только из-за наследования. В общем же случае экземпляр класса реализующий IDisposable следует окружать в using() { ... } или вызывать Dispose() самому.

Сборка мусора обширная тема. Советую прочитать книгу Рихтера CLR via C#. Хотя бы главу посвященную GC.
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38252522
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ок, такй вопрос - если вызвать Dispose() у большого обьекта который занимает много места, тот-же датасет, то становится-ли его память доступна для других обьектов еще до того как до него добрался сборщик мусора? т.е. помечается-ли эта память как свободная для новых обьектов процесса? Т.е. скажем такая ситуация - пользователь постоянно открывает новые окна с гридом, в которые закачивается много данных, скажем 50М, если ждать пока сборщик подберет мусор - процесс может сильно разрастись в размерах, а вот если каждый раз память из-под грида диспозится и переиспользуется для нового грида?
или такое в принципе невозможно в .net?
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38252524
WPF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Первая проблема, которая решается с помощью Dispose() это освобождения системных хэндлеров WinApi. В случае DataSet мы имеем только действующее соединение с БД. Если соединение закрыто, GC на запуске утилизирует ненужные более ссылки DataSet, это происходит не сразу, потому как GC управляется отдельным сервисом, в отдельном потоке по требованию или расписанию.
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38253187
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenfordесли вызвать Dispose() у большого обьекта который занимает много места, тот-же датасет, то становится-ли его память доступна для других обьектов еще до того как до него добрался сборщик мусора? т.е. помечается-ли эта память как свободная для новых обьектов процесса?
Нет и нет. В задачу Dispose() входить освободить т.н. неуправляемые ресурсы находящиеся вне зоны ответственности CLR/GC. Это освобождение может также выполнятся финализатором. IDisposable же нужен чтобы выполнить освобождение сразу как только ресурс стал ненужен.

stenfordТ.е. скажем такая ситуация - пользователь постоянно открывает новые окна с гридом, в которые закачивается много данных, скажем 50М, если ждать пока сборщик подберет мусор - процесс может сильно разрастись в размерах, а вот если каждый раз память из-под грида диспозится и переиспользуется для нового грида?
или такое в принципе невозможно в .net?
Во-первых, следует определиться нужно ли грузить данные в таких объемах. Постраничное разбиение и ленивая подрuузка могут уменшить кол-во используемой памяти и вопрос отпадет сам собой. Во-вторых, если такие объемы в самом деле нужны, то следует убеждаться что на неиспользуемые объекты не остается ссылок и предоставить GC освободить их или вручную вызывать GC.Collect() при закрытии формы.

WPFВ случае DataSet мы имеем только действующее соединение с БД.
Не вводи человека в заблуждение. DataSet не держит соединения с БД.
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38254071
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileНет и нет. В задачу Dispose() входить освободить т.н. неуправляемые ресурсы находящиеся вне зоны ответственности CLR/GC. Это освобождение может также выполнятся финализатором. IDisposable же нужен чтобы выполнить освобождение сразу как только ресурс стал ненужен.

непонятна такая вещь - если я не вызову Dispose(), то обьект через некоторое время будет уничтожен сборщиком мусора, а неуправляемые ресурсы будут все равно освобождены т.к. сборщик мусора вызовет Finalize() который и освободит их, верно? Что тогда таким образом сигнализирует CA2000: Dispose objects before losing scope - всего-лишь то, что неуправляемые ресурсы проживут в памяти немного дольше, чем если-бы я задиспозил их сразу?
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38254072
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но тогда непонятно следующее предложение -
Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead.

Как это файнолайзер может не выполниться из-за исключения? При чем тут исключение в коде, если файнолайзер запускается сборщиком мусора? Почему вдруг сборщик мусора окажется неспособным вызвать этот файнолайзер?
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38254104
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford,

по поводу стартового топика - действительно нужно вернуть из метода закрытый SerialPort ?
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38254110
SeVa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenfordНо тогда непонятно следующее предложение -
Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead.

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

Все просто. Во время вызова dispose может произойти исключение и сборщик мусора не отработает должным образом. Посему using нельзя использовать ,например, для wcf proxy. http://dave-black.blogspot.ru/2012/03/dont-use-using-with-wcf-proxy.html=]тынц
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38254111
SeVa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38254141
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeVaВсе просто. Во время вызова dispose может произойти исключение и сборщик мусора не отработает должным образом. Посему using нельзя использовать ,например, для wcf proxy.
я так понял что мой первоначальный пример не про using и не про исключение в Dispose(), в том примере

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Try
      tempPort = New SerialPort(PortName)
      tempPort.Open()
      SomeMethod()
      'Add any other methods above this line
      port = tempPort
      tempPort = Nothing 

   Finally 
      If Not tempPort Is Nothing Then
         tempPort.Close()
      End If 
   End Try 



исключение выбрасывается где-то при открытии порта или вызова SomeMethod(), т.к. этот метод должен вернуть SerialPort вызывающему методу. И идея такая что если возникло исключение, то в Finally оно будет поймано и порт закрыт. Спрашивается, зачем это делать если сборщик мусора все равно потом вызовет Finalize() у этого порта?
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38254144
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeVa тынц

там внизу под статьей есть правильное замечание :)

Dispose should not throw exceptions. Fix Dispose!
Dispose should not throw exceptions:
http://msdn.microsoft.com/en-us/library/bb386039.aspx
The work-around is insane!

Если Dispose() выкидывает исключения, то и действительно надо не воркэраунды лепить, а править Dispose()
...
Рейтинг: 0 / 0
CA2000: Dispose objects before losing scope
    #38254147
SeVa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenfordSeVa тынц

там внизу под статьей есть правильное замечание :)

Dispose should not throw exceptions. Fix Dispose!
Dispose should not throw exceptions:
http://msdn.microsoft.com/en-us/library/bb386039.aspx
The work-around is insane!

Если Dispose() выкидывает исключения, то и действительно надо не воркэраунды лепить, а править Dispose()

Те ты предлагаешь net переписать?
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / CA2000: Dispose objects before losing scope
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]