Подскажите, как работать с мусоросборщиком? Никогда не было необходимости самостоятельно контролировать, когда объект физически будет удален, но тут возникла проблема.
Проблема вытекла из другой: ошибка (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();
Ответ
Проблема оказалась не в том, что я не убиваю объекты, а то, что сам провайдер их у себя хранит копию на них. Т.о. когда я убиваю коннект, он еще живет внутри провайдера в pollе. Как оказалось, решение проблемы лежало на поверхности. Для моих нужд я опциями строки подключения выключил использования пулла коннектов и все заработало так, как мне нужно. Благодарю Вас за беспокойство к моей проблеме.
Комментариев нет:
Отправить комментарий