Я использую эту библиотеку для запроса базы данных sqlite с использованием mono:
https://www.mono -project.com / docs / доступ к базе данных / provider / sqlite /
И вот как я использую библиотеку:
var dbLocation = "/var/log/asterisk/master.db";
var conString = $"Data Source={dbLocation}; Read Only=True; Pooling=True;";
using (var sqlite3 = new Mono.Data.Sqlite.SqliteConnection(conString)
{
try
{
sqlite3.Open();
// query database
using(var command = sqlite3.CreateCommand()){
command.CommandText = "select * from foo";
var reader = command.ExecuteReader();
// etc...
reader.Close(); // close reader
}
}
catch
{
// log error
}
}
Обратите внимание, этот код выполняется каждую секунду.Другие процессы (Asterisk) записывают в базу данных, а мои процессы читают из базы данных.Я не могу оставить соединение открытым, потому что если я это сделаю, Asterisk не сможет записать в эту базу данных;поэтому я должен открывать и закрывать соединение каждый раз, когда планирую запрашивать базу данных.
Этот код прекрасно работает!Я могу запросить базу данных в режиме только для чтения.Я создал строку подключения на основе этой ссылки:
http://docs.go -mono.com /? Link = T% 3aMono.Data.Sqlite.SqliteConnection
Этот кодработает отлично, но через 2 дня моя программа падает, потому что sqlite.dll неправильно удаляет соединение.sqlite.dll оставляет соединения открытыми, и вот доказательство:
идентификатор процесса моего приложения: 29140:
Затем я выполнил команду lsof -a -p 29140
, и это возвращает мне что-то вроде этого:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
Main 29140 root cwd DIR 8,1 4096 46137345 /root
Main 29140 root rtd DIR 8,1 4096 2 /
Main 29140 root txt REG 8,1 3845024 12586404 /usr/bin/mono-sgen
Main ........
... etc
.... etc
Main 29140 root 74r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 75r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 76r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 77r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 78r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 79r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 80r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 81r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 82r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 83r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 84r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Main 29140 root 85r REG 8,1 39170048 49023734 /var/log/asterisk/master.db
Поскольку я запрашиваю базу данных каждую секунду, я ожидаю создать «блокировку файла» до /var/log/asterisk/master.db
каждую секунду.Это происходит случайно!Если база данных используется часто, я вижу увеличение числа /var/log/asterisk/master.db
.Как я могу правильно распорядиться этим sqlite-соединением?
Вещи, которые я пробовал:
Вызов GC.Collect()
и GC.WaitForPendingFinalizers()
, как следует из этих ответов: https://stackoverflow.com/a/8513453/637142