C# 收益回报完成后关闭IDataReader
实际上,它不必是C# 收益回报完成后关闭IDataReader,c#,ienumerable,yield-return,C#,Ienumerable,Yield Return,实际上,它不必是IDataReader 我有一个类似这样的函数: public IEnumerable<MyClass> GetObjects() { IDataReader dr = GetSomeDataReader(); while (dr.Read()) { yield return new MyClass(dr); } CloseDBConnections(); } public IEnumerable GetObjects() { IDat
IDataReader
我有一个类似这样的函数:
public IEnumerable<MyClass> GetObjects()
{
IDataReader dr = GetSomeDataReader();
while (dr.Read())
{
yield return new MyClass(dr);
}
CloseDBConnections();
}
public IEnumerable GetObjects()
{
IDataReader dr=GetSomeDataReader();
while(dr.Read())
{
新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);
}
}
public IEnumerable GetObjects()
{
IDataReader dr=GetSomeDataReader();
尝试
{
返回处理器读取器(dr);
}最后{
CloseDBConnections();
}
}
公共IEnumerable ProcessReader(IDataReader dr)
{
while(dr.Read())
{
新MyClass(dr)的收益回报率;
}
}
这不起作用,因为当执行CloseDBConnections()
时,枚举尚未处理
从GetObjects
返回时调用.ToList()
实际上是执行枚举,但此时连接已被破坏,IDataReader
失败
在我的实例中,无法从新的ProcessReader
函数中调用CloseDBConnections
,因为IDataReader
可能来自其他源(此实例中重新分解的全部要点)
是否有一个合理的解决方法,或者我必须复制枚举代码
我尝试将对
ProcessReader
的调用作为yield return
而不是return
,但这不起作用,因为C#(可以理解)认为我正在尝试将IEnumerable
添加到IEnumerable
不漂亮,但这应该行得通
public IEnumerable<MyClass> GetObjects()
{
IDataReader dr = GetSomeDataReader();
try
{
foreach (var result in ProcessReader(dr))
{
yield return result;
}
} finally {
CloseDBConnections();
}
}
public IEnumerable GetObjects()
{
IDataReader dr=GetSomeDataReader();
尝试
{
foreach(ProcessReader(dr)中的var结果)
{
收益结果;
}
}最后{
CloseDBConnections();
}
}
如何通过回调调用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 GetObjects()
{
返回ProcessReader(GetSomeDataReader(),CloseDBConnections);
}
公共IEnumerable ProcessReader(IDataReader dr,操作已完成)
{
尝试
{
while(dr.Read())
新MyClass(dr)的收益回报率;
}
最后
{
如果(OnFinished!=null)
OnFinished();
}
}
是的,我确实考虑过了。我希望有一个更干净的解决方案(比如一些神奇的关键字之类的)。在这种情况下,如果上述解决方案是唯一可能的解决方案,那么似乎不值得费心重新考虑。我想我可能希望太多了!您应该在finally
中执行回调。否则,如果迭代提前完成(例如,GetObjects().First()
),它将不会执行。@DominicKexel我喜欢它。这就是为什么我最终做了很多事情Javascript@svick我没有意识到这一点-我想这意味着原始代码应该有相同的try/finally,原因相同。@DJL是的,你是对的,finally
在那里也是必要的。