![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| N1ko |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 383 Регистрация: 30.12.2007 Где: Киев Репутация: нет Всего: нет |
Здравствуйте. Есть программа, которая сканируют 7 Гб dbf файлов и вставляет инфу из них в другую СУБД. Сканирует их до тех пор, пока не вылетает исключение "Недостаточно системных ресурсов". Запустив програму заново и при этом запустив диспетчер задач,увидел что количество дескрипторов непрерывно растёт. Когда доходит почти до 30000 собственно и вылетает исключение. Нашёл в интренете инфу, что такая проблема возникает в связи с использованием многопоточности.(Реализую её через стандартную компоненту BackGrounWorker) А вот как её решить не совсем понятно. Помогите плз кто чем может.
|
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 6 Всего: 118 |
Вам нужно пройтись по всему коду в поисках объектов, которые вы создаете, классы которых наследуются от IDisposable [http://msdn.microsoft.com/en-us/library/system.idisposable.aspx]. Далее очень внимательно погуглить по этому интерфейсу и почитать MSDN. Думаю ресурсы как раз и текут и вас в силу недетерменированной природы деструкторов (финализаторов) в .NET - среда просто не успевает разрушать объекты, содержащие ссылки на неуправляемые ресурсы (дескрипторы), и винда глушит ваше приложение.... возможно также, что ошибка в библиотеках которые вы используете подобная имеется.
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| N1ko |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 383 Регистрация: 30.12.2007 Где: Киев Репутация: нет Всего: нет |
То есть если я правильно понял нужно реализовать IDisposable у всех самодельных классов?
|
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 6 Всего: 118 |
N1ko, нет неправильно. IDisposable нужен если вам нужно относительно детерменированное (читай "по запросу вами") очистка ресурсов например.
Вам надо пройтись по коду и найти места где вы используете классы, наследуемые от IDisposable ... например OleDBConnection наследуется...а дальше using-и использовать или try..finally В общем тут почитайте http://www.rsdn.ru/article/dotnet/GCnet.xml -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| N1ko |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 383 Регистрация: 30.12.2007 Где: Киев Репутация: нет Всего: нет |
Пробовал как вы сказали. Прочитал кучу статей. Уже по 5 раз прошёлся по всему коду. Сделал Dispose у всего что только можно. Ничего не получается ((
Вот выложил код, котрый непосредственно отвечает за считывание данных из одного DBF файла и вставляет их в SQLite. Програма в принципе работает без утечки в случае если я не закрываю OleDbReader а в final прописываю GC.Collect(); GC.WaitForPendingFinalizers(); Но где то на 600-700 мб просканеных дбф файлов програма начинает работать очень медленно. Судя по всему из-за сборщика мусора. Возможно глядя на код Вы найдёте ошибку. Буду очень благодарен за Вашу помощ.
Это сообщение отредактировал(а) N1ko - 26.5.2010, 12:29 |
|||
|
||||
| NightmareZ |
|
|||
![]() [хакер] ![]() ![]() Профиль Группа: Участник Сообщений: 699 Регистрация: 10.8.2006 Репутация: 1 Всего: 13 |
Я считаю, что этого делать не нужно. Нужно лишь вызывать Dispose. Ты уверен, что ошибка тут? Не пробывал отслеживать, где дескрипторы создаются и где уничтожаются? -------------------- NightmareZ.net - мой блог и сайт, мои проекты и прочий трэш Ely-Art.ru - наша маленькая домашняя арт-студия mugcraft.ru - кружки на любой вкус |
|||
|
||||
| N1ko |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 383 Регистрация: 30.12.2007 Где: Киев Репутация: нет Всего: нет |
А может ли быть утечка дескрипторов из-за того что я сначала создаю SQLiteCommand, создаю в нём параметры. Но не устанавливаю в них Value. А уже только потом меняю эти значения в цикле много раз. Для этого SQLiteCommand не делаю Dispose()
И ещё мне вообще не понятно почему когда я убираю _oleDBReader.Close(); _oleDBReader.Dispose(); но оставляю GarbageCollector всё работает нормально без утечек. Это сообщение отредактировал(а) N1ko - 27.5.2010, 11:03 |
|||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 17 Всего: 306 |
а каков механизм сканирования? основан на DataReader, и если да, какой запрос его формирования? Добавлено через 4 минуты и 49 секунд этот код в блоке finally не нужен. Там достаточно _oleDBReader.Close(). И, следовательно, последний можно удалить из try catch вместе с _oleDBReader.Dispose() |
|||
|
||||
| N1ko |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 383 Регистрация: 30.12.2007 Где: Киев Репутация: нет Всего: нет |
Для сканирования действительно использую DataReader. Но к сожалению не совсем понял, что Вы имели ввиду под запросом формирования.
А как же я в блок finally вставлю _oleDBReader.Close(), если у него область видимости очень маленькая. Ведь Oledbreader я создаю в блоке try. Это сообщение отредактировал(а) N1ko - 27.5.2010, 11:21 |
|||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 17 Всего: 306 |
||||
|
||||
| N1ko |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 383 Регистрация: 30.12.2007 Где: Киев Репутация: нет Всего: нет |
Да. DbfFile - экземпляр класа, который хранит информацию о местонахождении DFB файла, его размере и тп. Метод ReadData() вытаскивает из него всю инфу.
В finally вряд ли получится закрывать Reader, потому что область видимости не позволяет.(Если оюъявить oledbreader перед блоком try) тогда в finally пишет ошибку "unassigned local variable" Это сообщение отредактировал(а) N1ko - 27.5.2010, 11:44 |
|||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 17 Всего: 306 |
ну это не проблема - можно и так:
не нужен ни Close() ни finnaly вот это и интересно. думаю не 7Gb? |
|||
|
||||
| N1ko |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 383 Регистрация: 30.12.2007 Где: Киев Репутация: нет Всего: нет |
Нет файлов очень много, каждый из которых от 20 до 400 кб.
В общем суть програмы следующая . Пользователь указывают папку, которую нужно просканировать на наличие DBF файлов, вытащить из них инфу и вставить в СУБД. Делаю я это посредством рекурсии. Соответственно DbfFile.ReadData() работает не с 7 Гб одновременно а работает с маленькими объёмами А можно ли как то очистить ресурсы выделенные под String после их затирания? Как я уже писал всё время использую один и то же SQLiteCommand, затирая Value для всех параметров и ставя на их место новые. Это сообщение отредактировал(а) N1ko - 27.5.2010, 12:10 |
|||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 17 Всего: 306 |
string.Empty? В целом ясно. Идея в принципе работоспособная (настораживает только рекурсия - net обладает отличной библиотекой по работе с каталогами). Имхо проблема, скорее всего просто в проектировании. По данному примеру тяжело судить о том что творится в целом. Подозреваю, что работа с базами у вас свалена вся в один класс, a стоило бы разделить работу с сущностями по отдельным, etc |
|||
|
||||
| N1ko |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 383 Регистрация: 30.12.2007 Где: Киев Репутация: нет Всего: нет |
Нет Я уже на этом прокололся недавно. И всё разграничил по сущностям. Для базы создал классы реализующие обёртку для самой БД, таблиц, полей, операций вставки, селекта и тп. В этом смысле вроде бы подход уже нормальный. Хотя изначально всё действительно было свалено в одну кучу.
|
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | .NET для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |