C# 如何取消IEnumerable?
在返回C# 如何取消IEnumerable?,c#,.net,ienumerable,C#,.net,Ienumerable,在返回IEnumerable的方法中,我打开并循环一个资源(例如数据库行读取器)。循环完成后,资源将再次关闭 但是,调用方可能决定不完成枚举。这使资源保持打开状态 例如: IEnumerable<Foo> Bar () { using (var r = OpenResource()) { while (r.Read ()) { yield return r; } } } // OK - this closes
IEnumerable
的方法中,我打开并循环一个资源(例如数据库行读取器)。循环完成后,资源将再次关闭
但是,调用方可能决定不完成枚举。这使资源保持打开状态
例如:
IEnumerable<Foo> Bar ()
{
using (var r = OpenResource()) {
while (r.Read ()) {
yield return r;
}
}
}
// OK - this closes the resource again
foreach (var foo in Bar()) {
Console.WriteLine (foo);
}
// Not OK - resource stays open!
Console.WriteLine (Bar().First());
IEnumerable条()
{
使用(var r=OpenResource()){
while(r.Read()){
收益率r;
}
}
}
//确定-这将再次关闭资源
foreach(Bar()中的变量foo){
Console.WriteLine(foo);
}
//不正常-资源保持打开状态!
Console.WriteLine(Bar().First());
我该如何解决这个问题?我是否可以轻松地取消枚举,即告诉它跳过循环的其余部分,或对其进行处置(将清理代码放入dispose
)
我考虑返回一个
Func
,这样如果用户完成了迭代,就可以让它返回false
。类似地,也可以使用某种取消令牌。但这两种方法对我来说似乎都很麻烦。通常是IEnumerator
实现了IDisposable
,如果您查看IEnumerator
的定义,您会看到:
public interface IEnumerator<out T> : IDisposable, IEnumerator
以任何方式退出foreach
(异常情况下,break
,自然完成res
),应调用IEnumerator
的Dispose()
。有关如何实现foreach
的示例,请参见(atry
…finally
…在finally
中使用Dispose()
)
请注意,C#将使用产生函数中使用的生成“正确”代码。请参见此处的示例:
和/或如果存在例外情况
catch
{
this.System.IDisposable.Dispose();
我搜索了一下,没有发现类似的问题,尽管我确信应该有一个——在我看来,这是一个非常基本的问题。break
应该取消它,生成的代码应该处理枚举数。如果源代码不能正确执行操作,则需要修复。@DanielA.White我想在调用方范围内取消它,而不是在枚举方法内部。请发布一个示例。如何将该方法包装到任务中并使用任务取消?
public IEnumerable<Foo> Bar()
{
using (var r = OpenResource())
{
while (r.Read ())
{
yield return new Foo();
}
}
}
void IDisposable.Dispose()
{
int num = this.<>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
this.<>m__Finally1();
}
}
}
if (!this.<r>5__1.Read())
{
this.<>m__Finally1();
catch
{
this.System.IDisposable.Dispose();