Есть ли в C # гарантии, что оператор using не унаследует проблемы с комбинациями try + finally?

Есть ли в C # гарантии, что оператор using не унаследует проблемы с комбинациями try + finally?

Вопрос, естественно, следует за обсуждением других здесь.

Согласно документации:

using (var font1 = new Font("Arial", 10.0f)) 
{
    byte charset = font1.GdiCharSet;
}

Пример кода ранее расширяется до следующего кода во время компиляции (обратите внимание на дополнительные фигурные скобки для создания ограниченной области для объекта):

{
  var font1 = new Font("Arial", 10.0f);
  try
  {
    byte charset = font1.GdiCharSet;
  }
  finally
  {
    if (font1 != null)
      ((IDisposable)font1).Dispose();
  }
}

Итак, есть ли гарантии, что метод finally для .Dispose будет вызываться все время в C #? В случае, если это так, означает ли это, что using фактически расширится до чего-то другого, чем просто комбинация try + catch?

ОБНОВЛЕНИЕ

В двух словах, о чем идет речь. Существует известная проблема, не позволяющая использовать комбинацию try + finally. Проблема обсуждается здесь. В вопросе я спрашиваю, относится ли проблема к using, поскольку using совпадает с комбинацией try + catch (согласно документации, указанной выше).


person qqqqqqq    schedule 10.02.2020    source источник
comment
Я ожидаю, что у него будет такое же ограничение, поэтому, если вам нужно с этим справиться, вам нужно будет обернуть using в _2 _ / _ 3_ (но я не знаю наверняка)   -  person Rufus L    schedule 11.02.2020
comment
это не имеет значения, если вы не справитесь с этим, ваше приложение вот-вот завершится и будет очищено.   -  person Keith Nicholas    schedule 11.02.2020
comment
@RufusL, о каком ограничении ты говоришь? Единственное ограничение, о котором я знаю, это то, что комбинация try + finally всегда должна включать блок catch, что означает, что try + finally никогда не должно происходить, в то время как try + catch + finally должен использоваться. Но я не уверен, как добавить блок catch в оператор using.   -  person qqqqqqq    schedule 11.02.2020
comment
Некоторые исключения (например, StackOverflowException) просто не могут быть восстановлены. В таких случаях я не ожидал, что Dispose запустится, но, как сказал Кейт, это не имеет значения.   -  person    schedule 11.02.2020
comment
В вашей ссылке есть ответ на ваш вопрос, почему вы публикуете тот же вопрос?   -  person Train    schedule 11.02.2020
comment
Я не понимаю, о чем вы спрашиваете. Если вам нужен блок catch, реализуйте его. Если нет, не надо.   -  person mason    schedule 11.02.2020
comment
@KeithNicholas, а что, если я открою ресурс на другом сервере? И он разработан таким образом, что его можно только закрыть явно? Это всего лишь один пример того, когда полезно иметь контроль над исключениями в приложении.   -  person qqqqqqq    schedule 11.02.2020
comment
Я говорю о ситуации из вашего другого вопроса, где у вас есть другой код, который должен выполняться в блоке finally. Поскольку у вас нет контроля над блоком finally, который генерирует using, вам придется добавить свой собственный try/finally вокруг using   -  person Rufus L    schedule 11.02.2020
comment
Да, метод Dispose будет вызываться для объекта, для которого создан блок using, за исключением некоторых чрезвычайно исключительных обстоятельств (которые блок finally не предотвратил бы ни то, ни другое), например StackOverflowException или AccessViolationException.   -  person mason    schedule 11.02.2020
comment
Использование блока похоже на try-finally с dispose() без обработки исключений, в основном то же самое.   -  person Train    schedule 11.02.2020
comment
@qqqqqqq тогда, если у вас НЕТ хотя бы обработчика исключений верхнего уровня, у вас есть ошибка. В любом случае ваше приложение закрывается. Если у вас возникла такая надуманная ситуация, у вас будут НАМНОГО большие проблемы, так как есть разные способы убить приложение, не имея возможности очистить его.   -  person Keith Nicholas    schedule 11.02.2020
comment
Сама документация охватывает это: The using statement ensures that Dispose is called even if an exception occurs within the using block. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.   -  person mason    schedule 11.02.2020
comment
Найден идеальный дубликат: stackoverflow.com/a/47153949/717732 (и хороший ответ с некоторым обоснованием Эрика Липперта )   -  person quetzalcoatl    schedule 11.02.2020
comment
@qqqqqqq хороший вопрос, не многие вникают в этот уровень детализации (а иногда и попадают в ловушку!)   -  person Keith Nicholas    schedule 11.02.2020
comment
Упомянутая вами известная проблема относится к необработанным исключениям , ситуации, в которых ваше приложение должно корректно завершиться в вашем unhandled exception handler. Любая память, неуправляемые ресурсы и объекты GDI будут автоматически освобождены Windows, когда ваш процесс все равно завершится. Что еще более важно, вы никогда не должны пытаться продолжить работу своего приложения при обнаружении необработанного исключения, потому что ваше приложение находится в неизвестном состоянии. Так что нет никаких проблем.   -  person MickyD    schedule 11.02.2020
comment
Спасибо всем за то, что помогли мне.   -  person qqqqqqq    schedule 11.02.2020