#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+""))
Комментариев нет:
Отправить комментарий