Страницы

Поиск по вопросам

воскресенье, 5 января 2020 г.

Удаление объекта, освобождение памяти в нужное для меня время

#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+""))

Комментариев нет:

Отправить комментарий