在按值与引用构造数据读取器时对其进行处理

本文关键字:处理 读取 数据 引用 | 更新日期: 2023-09-27 18:01:12

新手的问题是,当数据读取器在使用ref与var的类中构建时,它何时真正发布。我今天一直在测试这个问题,结果让我有点困惑——希望能在脑海中弄清楚这一点。

我有一个类,用于通过ODBC从许多远程服务器获取数据,但我需要限制连接到每台服务器的ODBC连接数量,所以在打开另一台服务器之前,我要小心处理好数据读取器。简而言之,我有一个名为FillDataReader的方法,它接受一个数据读取器对象,并根据您的查询填充它并将其传递回。

如果我使用ref传递它,并从调用端处理数据读取器,那么一切都很好。连接会立即释放,客户端可以在不烧录连接的情况下填充另一个数据读取器。但是,如果我传递值,资源就不会释放,如果我从客户端打开另一个数据读取器,我现在有两个到该服务器的连接。

从概念上讲,我得到了区别——在ref中,只有一个地址被使用,因为它正在传递一个"指向指针的指针",而dispose释放了该资源。好吧,但即使传递值并在客户端进行显式处理,资源究竟是什么?我宁愿在这里传递值,这样我就可以在客户端使用漂亮的using构造,但更重要的是,我想更好地了解这里发生了什么。简而言之,这就是的样子

[DB提取类]

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函数是否以某种方式挂起了对堆上已分配空间的引用?我不确定我是否理解为什么——我知道这是在使用堆栈上数据读取器的地址的另一个副本来引用堆上的数据读取器对象,但当它超出范围时,这不是发布的吗?也许我需要更多的咖啡…

在按值与引用构造数据读取器时对其进行处理

由于调用代码需要接收引用才能释放对象,因此确实需要ref(或out(。否则,参数只传递给方法,而不会返回,因此drTemp不会使用在FillDataReader方法中创建的数据读取器进行更新。

请注意,您可能需要更改签名如下,以使意图更加明确:

public Result TryGetDataReader(string pQueryString, out System.Data.Odbc.OdbcDataReader pDataReader)

我建议的更改:

  • 引入了"Try"的命名约定,这在这种类型的方法中很常见
  • 使pDataReader成为out,因为在调用方法时不需要初始化它
  • 引入了"Result"类型,该类型应包含成功信息和错误消息(如果有(