Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 收益回报完成后关闭IDataReader_C#_Ienumerable_Yield Return - Fatal编程技术网

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
在那里也是必要的。