新手的问题是,当数据阅读器在使用ref与var在类中构造时,数据阅读器何时会真正释放。我今天一直在测试,结果让我有点困惑--希望能弄清楚这一点。
我有一个用于通过ODBC从多个远程服务器获取数据的类,但我需要限制连接到每个服务器的ODBC连接的数量-因此,在使用完数据读取器后,在打开另一个数据读取器之前,我要小心正确地处理它们。简而言之,我有一个名为FillDataReader的方法,它接受一个数据读取器对象,并根据您的查询填充它,然后将其传递回来。
如果我使用ref传递它,并从调用端处理数据读取器,那么一切都很好。该连接被立即释放,并且客户端可以在不烧毁连接的情况下获得另一个数据读取器。但是,如果我通过值传递,资源不会被释放,并且如果我从客户端打开另一个数据读取器,我现在有两个到该服务器的连接。
从概念上讲,我得到了不同之处--在ref中,只有一个地址被使用,因为它传递了一个“指向指针的指针”,dispose释放了该资源。好的,但是即使通过值传递并在客户端执行显式的dispose,持有资源的到底是什么?我宁愿在这里通过值传递,这样我就可以在客户端使用漂亮的using构造,但更重要的是,我想更好地了解这里发生了什么。简而言之,它看起来是这样的
DB fetch类
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,则连接不会被释放。它最终会消失,但我需要它立即消失(因此调用dispose)。
那么,DB fetch类中的fill函数是否以某种方式挂起了对堆上已分配空间的引用?我不确定这是为什么--我理解它是使用堆栈上的数据读取器的另一个地址副本来引用堆上的数据读取器对象,但是当它超出范围时,它不是释放了吗?也许我需要更多的咖啡…
发布于 2011-07-02 23:20:28
由于您的调用代码需要接收引用来释放对象,因此您确实需要一个ref (或out)。否则,参数只会传递给方法,而不会返回,这样drTemp就不会使用在FillDataReader方法中创建的数据读取器进行更新。
请注意,您可能希望更改签名,如下所示,以使意图更清晰:
public Result TryGetDataReader(string pQueryString, out System.Data.Odbc.OdbcDataReader pDataReader)我建议的改变是:
out”的命名约定,这种命名约定在这种类型的方法中很常见,因为在调用Result为"Result“类型时,不需要对其进行初始化,它应该包含成功信息和错误消息(如果有的话)https://stackoverflow.com/questions/6557792
复制相似问题