Как безопасно избавиться от объектов IAsyncDisposable, полученных с помощью await foreach?

Могу я сделать это с помощью 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
}

1 ответ

Решение

Учитывая 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)

Редактировать конечно кто-то уже просил.

Другие вопросы по тегам