产生IDisposable资源 [英] Yielding with an IDisposable resource

查看:93
本文介绍了产生IDisposable资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有适当的方法来利用可支配资源?返回的对象是IDisposable,但是要迭代的元素是.

Is there a proper way to yield through a disposable resource? The returned objects are IDisposable, but the element it is iterating through is.

这里是一个例子:

public static IEnumerable<T> Fetch(IEnumerable<Guid> ids)
{
    using (var client = new CouchbaseClient())
    {
        yield return ids.Select(s => s.ToString());
    }
}

现在,调用此操作不会处置获得的using资源.我知道我可以只返回ToList并立即将其全部返回,但是有没有办法适当地"处理此问题,还是我必须在IDisposable资源上保留一个标签,并在完成后手动进行处理?

Right now, calling this would not dispose the using resource obtained. I know I can just to a ToList and return it all at once, but is there a way to handle this "properly", or do I have to keep a tab on the IDisposable resource and dispose of it manually when I'm done?

推荐答案

简而言之,只要方法的调用者正确处理IEnumerator对象,您就不必担心.

In short, you don't need to worry about it as long as the caller of the method handles the IEnumerator objects properly.

IEnumerator实现IDisposable,并且在创建迭代器块时使用的逻辑实际上足够聪明,可以在处理迭代器块时执行所有未执行的finally块. using调用的结果是创建了一个finally块,这就是IDisposable资源的放置位置.

IEnumerator implementes IDisposable, and the logic used in creating the iterator blocks is actually smart enough to execute all un-executed finally blocks when it is disposed. A finally block is created as a result of the using call, and that is where the IDisposable resource is disposed.

只要从此IEnumerable创建的IEnumerator对象被完全迭代(在这种情况下,最后的MoveNext调用将到达using块的末尾并处置资源)或处置IDisposable客户端将被处置.

So as long as the IEnumerator objects created from this IEnumerable are either iterated fully (in which case the final MoveNext call will reach the end of the using block and dispose of the resource) or disposed the IDisposable client will be disposed.

请注意,如果您担心代码的用户可能无法正确对待IEnumerator对象,那么最好不要使用带有延迟评估的迭代器块.如果您想确保即使调用者玩的不好",也要急切地评估该方法(即获取您拥有的代码,将结果转储到列表中,然后返回该列表).如果不分配资源的后果主要是或完全与性能有关(不释放较长时间的内存,保持打开连接状态等),那么可能就不必担心,但是如果永久保持锁定是一个问题.重大问题(即锁定的资源如果不释放就可能导致死锁),那么延迟评估的优势可能不值得.

Note that if you're concerned the user of your code may not treat the IEnumerator objects properly then you're best bet is to not use an iterator block with lazy evaluation. If you want to ensure that even if the caller doesn't "play nice" then eagerly evaluate the method (i.e. take the code you have, dump the results into a list, and then return that list). If the consequences of not disposing the resource are primarily, or entirely performance related (not releasing some memory for a while longer, keeping open a connection, etc.) then it may not be a concern, but if holding onto the lock forever is a major problem (i.e. a locked resource that could result in deadlocks if not released) then the advantage of lazy evaluation may not be worth it.

这篇关于产生IDisposable资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆