Вопрос новичка о том, когда действительно читатель выпускается, когда он построен в классе, используя ref
против var.Я тестировал это сегодня, и результаты меня немного озадачивают - в надежде разобраться в этом.
У меня есть класс, который я использую для извлечения данных через ODBC с многочисленных удаленных серверов, но мне нужночтобы ограничить количество соединений ODBC, открытых для каждого сервера, к которому я подключен, - поэтому я стараюсь правильно распределять устройства чтения данных, когда я закончу с ними, прежде чем открывать другой.Короткая версия: у меня есть метод с именем FillDataReader
, который принимает объект для чтения данных, заполняет его на основе вашего запроса и передает его обратно.
Если я передаю его с помощью ref
и удаляю устройство чтения данных извызывающая сторона, все хорошо.Соединение сбрасывается немедленно, и клиентская сторона может заполнить другой считыватель данных, не сжигая соединение.Однако, если я передам по значению, ресурс не будет освобожден, и если я открою другое устройство чтения данных со стороны клиента, у меня теперь будет два соединения с этим сервером.
Концептуально я понимаю разницу - с ref
используется только один адрес, так как он передает «указатель на указатель», и утилизация освобождает этот ресурс.Хорошо, но даже если передать по значению и сделать явное распоряжение на стороне клиента, что именно удерживает ресурс?Я предпочел бы передать здесь значение, чтобы я мог использовать изящную конструкцию using
на стороне клиента, но что более важно, я хочу лучше понять, что здесь происходит.Вкратце, вот как это выглядит
[класс извлечения БД]
public bool FillDataReader(string pQueryString, ref System.Data.Odbc.OdbcDataReader pDataReader, out string pErrorReason)
{
(uses a connection object that’s been established at class construction time and stays up all the time)
...
try
{
pDataReader = _Command.ExecuteReader();
}
...
}
[Calling class]
strSQL = "SELECT Alias, ObjectID, FROM vw_GlobalUser";
if (ServerList[currentServer].DatabaseFunctions.FillDataReader(strSQL, ref drTemp, false, out strErrorReason) == false)
….
drTemp.Dispose();
(at this point the connection is released to the server)
Однако, если я уберу ref
в точке Dispose в вызывающем классе, соединение не будетвышел.Это уходит в конце концов, но мне нужно, чтобы это ушло немедленно (отсюда и призыв избавиться).
Значит, функция заполнения в классе извлечения DB висит на ссылке на выделенное пространство в куче?Я не уверен, что понимаю, почему это так - понял, что он использует другую копию адреса для чтения данных в стеке для ссылки на объект чтения данных в куче, но когда он выходит из области видимости, разве это не освобождается?Может быть, мне нужно больше кофе ...