关于数据阅读器何时在使用ref
与var的类中构建时实际发布的新手问题。我今天一直在测试这个,结果令我感到困惑 - 希望能让我明白这一点。
我有一个类用于通过ODBC从众多远程服务器获取数据,但我需要限制对每个连接的服务器开放多少个ODBC连接 - 所以我要小心正确处理数据读取器当我在打开另一个之前完成它们的时候。简短版本是我有一个名为FillDataReader
的方法,它接受一个数据读取器对象,并根据您的查询填充它并将其传回。
如果我使用ref
传递它并从呼叫方处理数据阅读器,一切都很好。连接立即释放,客户端可以在不烧录连接的情况下填充另一个数据读取器。但是,如果我通过值传递,资源不会被释放,如果我从客户端打开另一个数据读取器,我现在有两个连接到该服务器。
从概念上讲,我得到了不同之处 - 使用ref
只使用了一个地址,因为它传递了一个“指向指针的指针”,并且dispose释放了该资源。好的,但即使通过值传递并在客户端进行显式处置,究竟是什么才能保留资源?我宁愿在这里传递值,所以我可以在客户端使用漂亮的using
构造,但更重要的是我想更好地理解这里发生的事情。简而言之,这就是它的样子
[DB fetch class]
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)
但是,如果我在调用类的Dispose处取出ref
,则不会释放连接。它最终消失但我需要它立即消失(因此要求处置)。
DB fetch类中的fill函数是否以某种方式挂在对堆上已分配空间的引用上?我不确定我理解为什么会这样 - 了解它正在使用另一个地址副本到堆栈上的数据读取器来引用堆上的数据读取器对象但是当它超出范围时,是不是已经发布了?也许我需要更多的咖啡......
答案 0 :(得分:0)
由于您的调用代码需要接收释放对象的引用,因此您需要ref
(或out
)。否则,该参数仅传递给方法,但不会返回,因此drTemp
不会使用FillDataReader
方法中创建的数据读取器进行更新。
请注意,您可能需要更改签名,以使意图更清晰:
public Result TryGetDataReader(string pQueryString, out System.Data.Odbc.OdbcDataReader pDataReader)
我建议的更改:
out
,因为在调用方法时不需要初始化