如何安全地处理使用 await foreach 检索的 IAsyncDisposable 对象?

6

我能使用 using var 来做这件事吗:

await foreach (var response in _container.GetItemQueryStreamIterator(query))
{
   using var safeResponse = response;
   //use the safeResponse
}

还是我应该这样做:
await foreach (var response in _container.GetItemQueryStreamIterator(query))
{ 
  try {
    //use response
  } finally {
    response?.Dispose();
  }
}

我是否可以不进行资源释放而直接使用迭代器,因为这个迭代器是一个 IAsyncDisposable,并且 await foreach会自动进行资源释放呢?

await foreach (var response in _container.GetItemQueryStreamIterator(query))
{
   //use the response
}

@TheodorZoulias 谢谢,非常有趣。 - fred_
1个回答

4

给定一个包含IEnumerable<IDisposable>的对象(带或不带Async),没有规则指定谁应该释放其中的元素。因此(并且希望如此),枚举它不会释放其元素。

释放这些元素是你的责任。

在你的问题中,你想在迭代时释放它们,所以选项3不可行,你必须自己处理释放。

选项1和2等效,但都有异味。

你可以这样写:

await foreach (var item in enumerable)
{
  await using (item)
  {
    ..          
  }
}

// by playing with your autoformatter
await foreach (var item in enumerable) await using (item)
{
  ..
}

很遗憾,我没有看到更好的解决方案。而且,如果你正在使用值类型(ValueType),你需要小心,看起来是这样。也许我们应该提出类似这样的要求:
await foreach(await using var e in c)

编辑 当然 已经有人提出了这个需求


谢谢,我会使用您的自动格式化建议 :) - fred_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接