#c_sharp
Подскажите, как работать с мусоросборщиком? Никогда не было необходимости самостоятельно контролировать, когда объект физически будет удален, но тут возникла проблема. Проблема вытекла из другой: ошибка (cannot start thread). Суть проблемы в том, что в цикле открываются и закрываются подключения к базе данных (к разным базам, перебираются порядка нескольких тысяч баз). Как оказалось, хоть и объект создается в блоке using() {} даже при выходе из этого блока подключение к базе остается висеть (на уровне сервера firebird). Все подключения мгновенно разорвутся, как только приложение будет закрыто. Остается у меня один вариант, что объект хоть и закрыл соединение и вызвался автоматически метод object.Dispose() по выходу из блока using, объект все еще висит в памяти, и тем самым не дает серверу разорвать соединение с базой. На форуме поддержки .net провайдера firebird мне сказали, что нужно научиться физически прибивать объекты, а не надеяться на мусоросборщики. Вот сижу теперь и гадаю, как этой подсказкой воспользоваться. По мануалу не разобрался как пользоваться GC.*. Точнее разные варианты попробовал, но проблема не решилась. Может просто не умею готовить?.. Кто сталкивался с необходимостью физического прибития объектов, подскажите, как мне избавиться от него в нужное мне время, а не когда мусоросборщик сам посчитает это необходимым. Заранее спасибо. UPD Вот что вижу на сервере Server Version Info --------------------------------------------------------------------------- Server Version: WI-V2.5.1.26351 Firebird 2.5 Server Implementation: Firebird/x86/Windows NT Service Version: 2 Configuration Info --------------------------------------------------------------------------- Base File: D:\Program Files\Firebird_2_5\ Lock File: C:\ProgramData\firebird\ Message File: D:\Program Files\Firebird_2_5\ Security Database: D:\Program Files\Firebird_2_5\security2.fdb Database Info --------------------------------------------------------------------------- Number of connections: 140 Number of databases: 140 Вот тестовая програмулина, которой проверял по вашим советам: FbConnectionStringBuilder builder = new FbConnectionStringBuilder(); builder.Dialect = 3; //builder.DataSource = "localhost"; builder.Password = "masterkey"; builder.UserID = "SYSDBA"; builder.Charset = "WIN1251"; for (int i = 0; i < fileList.Count; i++) { builder.Database = fileList[i]; using (FbConnection connection = new FbConnection(builder.ConnectionString)) { try { Console.WriteLine(string.Format("[{0}] - {1}", i.ToString("0000"), fileList[i])); connection.Open(); Console.WriteLine(string.Format("[{0}] Connected", i.ToString("0000"))); } catch (Exception ex) { Console.WriteLine(string.Format("[{0}] - EXCEPTION {1}" ,i.ToString("0000"), ex.Message)); Console.ReadKey(); } connection.Close(); Console.WriteLine(string.Format("[{0}] Disconnected", i.ToString("0000"))); } GC.Collect(); GC.WaitForPendingFinalizers(); } Console.ReadKey();
Ответы
Ответ 1
Проблема оказалась не в том, что я не убиваю объекты, а то, что сам провайдер их у себя хранит копию на них. Т.о. когда я убиваю коннект, он еще живет внутри провайдера в pollе. Как оказалось, решение проблемы лежало на поверхности. Для моих нужд я опциями строки подключения выключил использования пулла коннектов и все заработало так, как мне нужно. Благодарю Вас за беспокойство к моей проблеме.Ответ 2
Можно порекомендовать только вставить после using и обнуления ссылки два заклинания: GC.Collect(); GC.WaitForPendingFinalizers(); должно помочь, хотя может немного просесть производительность.Ответ 3
Вот есть у меня подозрение что из за этого builder.ConnectionString у вас объект и остаётся живым... пока билдер не прибьёте магия и не произойдёт... для проверки попробуйте или убить билдера или инициализировать так: using (FbConnection connection = new FbConnection(builder.ConnectionString+""))
Комментариев нет:
Отправить комментарий