gpt4 book ai didi

c# - 内部使用 yield

转载 作者:可可西里 更新时间:2023-11-01 03:02:13 25 4
gpt4 key购买 nike

如果我没记错的话,当我在 using SqlConnection block 中使用 yield 时,我遇到了运行时异常。

using (var connection = new SqlConnection(connectionString))
{
var command = new SqlCommand(queryString, connection);
connection.Open();

SqlDataReader reader = command.ExecuteReader();

// Call Read before accessing data.
while (reader.Read())
{
yield reader[0];
}

// Call Close when done reading.
reader.Close();
}

当我将 yield 替换为每次迭代都添加项目的列表时,这些问题得到了解决。

using StreamReader block 中时,我还没有遇到同样的问题

using (var streamReader = new StreamReader(fileName))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
yield return line;
}
}

是否有任何解释为什么异常发生在前者而不是后者?这种结构是否可取?

编辑 要获得我过去所做的错误(及早处理),您应该调用下面的第一个方法:

IEnumerable<string> Read(string fileName)
{
using (var streamReader = new StreamReader(fileName))
{
return Read(streamReader);
} // Dispose will be executed before ReadLine() because of deffered execution
}

IEnumerable<string> Read(StreamReader streamReader)
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
yield return line;
}
}

同样的错误可以通过其他延迟执行的方式来实现,例如 System.Linq.Enumerable.Select()

最佳答案

参见 this post以很好地解释 usingyield 的问题。因为您在枚举器中返回,所以在访问任何内容之前,using block 已经破坏了上下文。答案有很好的解决方案,基本上,要么使包装器方法成为枚举器,要么构建一个列表。

此外,在阅读器周围使用 using 而不是连接通常更实用,并使用 CommandBehavior.CloseConnection 确保在阅读器完成后释放资源。尽管在您的情况下这并不重要,但如果您从方法中返回数据读取器,这将确保在处理读取器时正确关闭连接。

   using(SqlDataReader reader = 
command.ExecuteReader(CommandBehavior.CloseConnection)) {
while (reader.Read())
{
yield reader[0];
}
}

关于c# - 内部使用 yield ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5716350/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com