Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Ногами не бить - я новенький Добавлено: 25.03.11 16:23  

Автор вопроса:  час1
написал я функцию:

 Function FUN_CREATE_FILE(ByVal NAME_FILE As String) As Boolean
        ' Создаем новый текстовой файл с именем NAME_FILE
        Try
            File.Create(NAME_FILE)

            Return True
        Catch ex As Exception
            Return False
        Finally

        End Try

    End Function

работает она нормально, но при анализе кода - мне сообщают, что:
Предупреждение 31 CA2000 : Microsoft.Reliability : В методе 'FILE_MOD.FUN_CREATE_FILE(String)' вызовите System.IDisposable.Dispose для объекта 'File.Create(NAME_FILE)' перед тем, как все ссылки на него будут вне области видимости. C:\1_Текущее\1_2010\MODULS\MODULS\FILE_MOD.vb 75 MODULS

потыкался - посмотрел что написано об этом в msdn? поискал ответы в инете.
ответы есть - примеры то же - ничё не понимаю.
Как в моём случае высвободить уже неиспользуемые ресурсы?

Ответить

  Ответы Всего ответов: 10  

Номер ответа: 1
Автор ответа:
 час1



Вопросов: 5
Ответов: 35
 Профиль | | #1 Добавлено: 25.03.11 16:29
Помогите понять Простой пример:

Dim contents As String
    
Using reader As New StreamReader("somefile.txt";)
    contents = reader.ReadToEnd();
End Using

как это к моему коду - можно применить?
чёта ничё не понимаю.....

Ответить

Номер ответа: 2
Автор ответа:
 Лёха



Вопросов: 20
Ответов: 79
 Web-сайт: supersait16.ucoz.ru
 Профиль | | #2
Добавлено: 25.03.11 20:16
в этом коде ты создаешь StreamReader,который предназначен для считывания информации с файла(можно и по названию догадаться),потом ты считуешь все, что есть в файле в переменную contents.

Ответить

Номер ответа: 3
Автор ответа:
 СанСаныч



Вопросов: 3
Ответов: 118
 Профиль | | #3 Добавлено: 25.03.11 20:24
потыкался - посмотрел что написано об этом в msdn? поискал ответы в инете.
ответы есть - примеры то же - ничё не понимаю.

Может, есть смысл забросить программирование? Или в универ на нужную специальность поступить...

Ответить

Номер ответа: 4
Автор ответа:
 Лёха



Вопросов: 20
Ответов: 79
 Web-сайт: supersait16.ucoz.ru
 Профиль | | #4
Добавлено: 25.03.11 21:06
Как в моём случае высвободить уже неиспользуемые ресурсы?

Ты используешь управляемый код,все не нужные ресурсы освободит GC.

Ответить

Номер ответа: 5
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #5 Добавлено: 25.03.11 21:58
Лёха пишет:
Ты используешь управляемый код,все не нужные ресурсы освободит GC.

неправда.
Хоть код и управляемый, но GC может освободить только управляемые ресурсы. О не управляемых ресурсах он ничего не знает.

По поводу предупреждения в первом сообщении.
Метод File.Create создает файл и возвращает тебе экземпляр FileStream, через который можно выполнять запись/чтение данных.
--------------
Посмотирм что происхоидт на более нижнем уровне.
Можно предположить, что для создания вызывается функция Win32API CreateFile. Она возвращает указать (handle) на объект файла (file), который в данном случае уже является неуправляемым объектом. Этот handle записывается в какое-то внутреннее поле экземпляра класса FileStream. Кстати его можно узнать, обратившись к свойству FileStream.SafeFileHandle

В документации на CreateFile мы видим что:
When an application is finished using the object handle returned by CreateFile, use the CloseHandle function to close the handle. This not only frees up system resources, but can have wider influence on things like sharing the file or device and committing data to disk. Specifics are noted within this topic as appropriate.


То есть после того как работа с файлом завершена, необходимо вызвать метод CloseHandle, указав handle объекта, который мы хотим закрыть. Это не только предотвратит утечку памяти, но также освободит файл от блокировки, дав возможность другим приложениям работать с ним (если общий доступ был запрещен при создании FileStream), то есть, закрывать файл желательно как можно раньше, в идеале - как только работа с ним закончилась.
--------------

Разумеется, дотнет это не VB6, в дотнете нет необходимости вручную вызывать метод CloseHandle. Каждый класс, который создает неуправляемые ресурсы, должен знать как неуправляемые ресурсы удалять. И предоставлять возможность это сделать.

По общепринятой рекомендации класс, с которым связаны неуправляемые ресурсы, или которому просто по какой-то причине нужно выполнять детерменированное удаление управляемых или неуправляемых ресурсов, должен реализовывать интерфейс IDisposable. В этом интерфейсе только один метод - Dispose, при вызове которого и должно происходить удаление ресурсов и другие операции. Например, в случае FileStream перед закрытием файла в него предварительно будет сброшено содержимое буфера.

То есть, когда ты завершил работу с объектом, который реализует IDisposable, нужно вызвать у него метод Dispose.

  1.     Dim Stream As FileStream = File.Create("c:\1.txt")
  2.     ' Здесь идет работа с потоком
  3.     Stream.Dispose()

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

  1.     Dim Stream As FileStream
  2.     Try
  3.         Stream = File.Create("c:\1.txt")
  4.         ' Здесь идет работа с потоком
  5.     Finally
  6.         If Stream IsNot Nothing Then
  7.             Stream.Dispose()
  8.         End If
  9.     End Try


Ввиду излишней сложности данной конструкции, в язык была введена более простая конструкция (кстати в C# она была еще с первой версии)
  1.     Using Stream = File.Create("c:\1.txt")
  2.         ' Здесь идет работа с потоком
  3.     End Using


Ты можешь использовать последний приведенный вариант кода. Просто в твоем случае никакого кода работы с потоком не будет.

----------------------

В .NET есть предохранитель на тот случай если программист забудет вызвать метод Dispose у объекта и он пропадет из области видимости. В этом случае до него доберется сборщик мусора, увидит что на него нет ссылок. А также увидит что у объекта есть финализатор, и поставит его в очередь на финализацию. После этого у объекта будет вызван финализатор. В финализеторе есть проверка того, был ли вызван Dispose, и если не был, то он будет вызван принудительно. Таким образом, неуправляемый ресурс все равно будет удален, только позже.

Но здесь есть 2 проблемы.
1. Время запуска сборщика мусора и финализаторов недетерменировано. То есть, может пройти определенное время между тем моментом когда работа с файлом завершена, и моментом запуска сборщика мусора. Все это время неуправляемые ресурсы будут висеть (а это могут быть и довольно дорогие ресурсы). Кроме того, если работа с файлом была длительное время, то объект мог уйти во 2-е поколение, и тогда есть большая вероятность, что при запуске сборщика мусора он не доберется до этого объекта и он будет продолжать висеть. И будет удален только тогда когда кончится свободная память и сборщик мусора не возьмется за 1 и 2 поколение объектов. Также между сборкой мусора и запуском финализаторов может пройти неопределенное время.
2. CLR не гарантирует что финализаторы будут запущены, даже если объект удален при сборке мусора. Хотя обычно финализаторы запускаются, но на 100% нельзя на это полагаться.

Вызов Dispose при финализации не всегда выполняется автоматически, это не фича CLR. Вызов Dispose будет только в том случае, если в классе есть финализатор, и если программист, делавший этот класс, сделал в финализаторе вызов Dispose. Поэтому не нужн думать, что это актуально для каждого объекта.

Ответить

Номер ответа: 6
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #6 Добавлено: 25.03.11 22:14
Также обращаю внимание, что в VB .NET не используется такая нотация.

Вместо этого принято что-то вроде
  1. Function CreateFile(ByVal fileName As String) As Boolean


UPPER_CASE используется только для констант и то не всегда.

Ответить

Номер ответа: 7
Автор ответа:
 AgentFire



ICQ: 192496851 

Вопросов: 75
Ответов: 3178
 Профиль | | #7 Добавлено: 25.03.11 22:40
я думаю, тебе можно писать книги.

Ответить

Номер ответа: 8
Автор ответа:
 час1



Вопросов: 5
Ответов: 35
 Профиль | | #8 Добавлено: 25.03.11 23:00
Огромное спасибо!!!
Зря я второй вопрос написал - потому как это не вопрос, а пример как "занимать" и освобождать ресурсы.
Он не имеет косвенное отношение к дискуссии, но немного сбил всех с толку - жаль.

Ответить

Номер ответа: 9
Автор ответа:
 час1



Вопросов: 5
Ответов: 35
 Профиль | | #9 Добавлено: 25.03.11 23:52
СанСаныч пишет:
Может, есть смысл забросить программирование? Или в универ на нужную специальность поступить...

=================
Спасибо за совет.
Ни то ни другое - мне не подходит.

Ответить

Номер ответа: 10
Автор ответа:
 час1



Вопросов: 5
Ответов: 35
 Профиль | | #10 Добавлено: 26.03.11 09:01
Artyom
Теперь, когда внесена ясность и расставлены точки - появляются и ответы в инете.
Ещё раз Благодарю за подробнейший ответ.
============================================
http://www.vbnet.ru/articles/showarticle.aspx?id=163#IDAAPLCG

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам