在收益率返回完成后关闭IDataReader
本文关键字:IDataReader 收益率 返回 | 更新日期: 2023-09-27 18:24:45
实际上它不必是IDataReader
。
我有一个类似的功能:
public IEnumerable<MyClass> GetObjects()
{
IDataReader dr = GetSomeDataReader();
while (dr.Read())
{
yield return new MyClass(dr);
}
CloseDBConnections();
}
这一直运行良好,直到我这样重构它:
public IEnumerable<MyClass> GetObjects()
{
IDataReader dr = GetSomeDataReader();
try
{
return ProcessReader(dr);
} finally {
CloseDBConnections();
}
}
public IEnumerable<MyClass> ProcessReader(IDataReader dr)
{
while (dr.Read())
{
yield return new MyClass(dr);
}
}
这不起作用,因为当执行CloseDBConnections()
时,枚举尚未处理。
在GetObjects
返回时调用.ToList()
是实际执行枚举的操作,但此时连接已被破坏,IDataReader
失败。
在我的例子中,CloseDBConnections
不能从新的ProcessReader
函数中调用,因为IDataReader
可能来自其他来源(在这个例子中,重新分解的整个点)
有没有一个合理的解决方法,或者我必须复制枚举代码?
我尝试将对ProcessReader
的调用作为yield return
而不是return
,但这不起作用,因为C#(可以理解)认为我正在尝试将IEnumerable
添加到IEnumerable
!
在ProcessReader
中通过回调调用CloseDBConnections
怎么样?
public IEnumerable<MyClass> GetObjects()
{
return ProcessReader(GetSomeDataReader(), CloseDBConnections);
}
public IEnumerable<MyClass> ProcessReader(IDataReader dr, Action OnFinished)
{
try
{
while (dr.Read())
yield return new MyClass(dr);
}
finally
{
if (OnFinished != null)
OnFinished();
}
}
虽然不漂亮,但应该可以。
public IEnumerable<MyClass> GetObjects()
{
IDataReader dr = GetSomeDataReader();
try
{
foreach (var result in ProcessReader(dr))
{
yield return result;
}
} finally {
CloseDBConnections();
}
}