Здравствуйте, drol, Вы писали:
D>Здравствуйте, Aviator, Вы писали:
A>>У тебя из finally вылетает исключение
D>Да без разницы откуда оно вылетает — finally-блоки поэтому и finally, бо в нормальном потоке исполнения они отрабатывают в независимости от того что и откуда вылетело. Если в finally нужна логика в которой возможны свои исключения — ну так пишите try\catch и ловите их там.
Специально для тех, кто на бронепоезде. Выше писалось, что в с++ нефик из деструкторов кидать исключения, в ответ было заявлено, что в c# можно отлично кидать из Dispose и всё будет шоколадно. Я третий пост объясняю, что шоколадно не будет. Вопрос — к чему вообще относится данный пост?
L>О том и речь. Потому говорить "используют именно его" некорректно.
L>Там просто не надо было использовать using, он там не нужен.
Э нет. С тобой несогласен не только я, но и разработчики System.Transactions. Там использование using для транзакций слева направо, так и справа налево. И заметь, очень визально чисто и красиво — если не считать явного Complete о котором вечно забывают. Да и понять что будет если вставить код между Dispose и коммитом. Но синтаксическая красивость всё перекрывает.
Я использую подобный механизм для пересылки контекстов вызова. Да и вообще, юзкейзов при которых подобный синтаксис будет в тему — вагон и маленькая тележка.
L>>О том и речь. Потому говорить "используют именно его" некорректно.
L>>Там просто не надо было использовать using, он там не нужен. GZ>Э нет. С тобой несогласен не только я, но и разработчики System.Transactions. Там использование using для транзакций слева направо, так и справа налево.
Здравствуйте, Aviator, Вы писали:
A>Специально для тех, кто на бронепоезде.
Специально для не умеющих читать:
A>Выше писалось, что в с++ нефик из деструкторов кидать исключения,
Выше писалось, что в C++ якобы очень здорово размещать код освобождения ресурсов в деструкторах, бо для локальных объектов на стеке и членов классов оные вызываются в нужный момент автоматически.
На что был задан очень простой вопрос: как через такие цепочки неконтролируемых вызовов деструкторов протаскивать наверх информацию об исключительных ситуациях возникших при освобождении ресурсов ?
Ответа так и не прозвучало.
A>что в c# можно отлично кидать из Dispose и всё будет шоколадно.
Будет не "шоколадно", а так как захочется пишущему на C#. В том числе можно добиться и "шоколадности" — сиречь получения (практически) полного дерева исключений возникших в вызове.
Что Вам непонятно ? Только с примером кода, пожалуйста. Желательно и на C++, и на C#
Здравствуйте, GlebZ, Вы писали:
L>>Ьам нет запихивания Commit-а в Dispose GZ>Согласен. Но только потому, что в нынешнем синтаксисе это сделать невозможно.
В нынешнем синтаксисе есть возможность сделать Commit транзакции в методе Dispose
Здравствуйте, Lloyd, Вы писали:
L>>>Ьам нет запихивания Commit-а в Dispose GZ>>Согласен. Но только потому, что в нынешнем синтаксисе это сделать невозможно.
L>В нынешнем синтаксисе есть возможность сделать Commit транзакции в методе Dispose
Занятно. Как? Я пытался что-то сделать подобное еще до 1.1, но без извращений типа ProfileAPI это было невозможно.
Здравствуйте, GlebZ, Вы писали:
L>>>>Ьам нет запихивания Commit-а в Dispose GZ>>>Согласен. Но только потому, что в нынешнем синтаксисе это сделать невозможно.
L>>В нынешнем синтаксисе есть возможность сделать Commit транзакции в методе Dispose GZ>Занятно. Как?
Вот так:
public void Dispose() {
Commit();
}
GZ>Я пытался что-то сделать подобное еще до 1.1, но без извращений типа ProfileAPI это было невозможно.
Здравствуйте, drol, Вы писали:
D>Здравствуйте, Aviator, Вы писали:
A>>Специально для тех, кто на бронепоезде.
D>Специально для не умеющих читать:
A>>Выше писалось, что в с++ нефик из деструкторов кидать исключения,
D>Выше писалось, что в C++ якобы очень здорово размещать код освобождения ресурсов в деструкторах, бо для локальных объектов на стеке и членов классов оные вызываются в нужный момент автоматически.
Так ведь это и правда очень здорово, в тех случаях, когда освобождение ресурса не приводит к ошибке. Имхо, таких случаев, всё-таки большинство.
D>На что был задан очень простой вопрос: как через такие цепочки неконтролируемых вызовов деструкторов протаскивать наверх информацию об исключительных ситуациях возникших при освобождении ресурсов ?
D>Ответа так и не прозвучало.
Ответа, разумеется, нет, с другой стороны, никто не мешает для таких ресурсов использовать другие способы освобождения, позволяющие передать всю нужную информацию наверх. В C++0x это даже будет не сильно страшно выглядеть.
Здравствуйте, k.o., Вы писали:
KO>Так ведь это и правда очень здорово, в тех случаях, когда освобождение ресурса не приводит к ошибке.
Это, конечно, здорово, но ведь даже такая элементарная вещь как, например, закрытие файла может влёгкую выдать ошибку, нуждающуюся в корректной реакции.
KO>Имхо, таких случаев, всё-таки большинство.
Вы уверены ? Ну тогда давайте, перечислите ресурсы, освобождение которых гарантированно корректно и не даёт перехода в fail-состояния.
KO>Ответа, разумеется, нет, с другой стороны, никто не мешает для таких ресурсов использовать другие способы освобождения, позволяющие передать всю нужную информацию наверх.
У оппонентов наконец-то начинает возникать понимание Конечно, сделать аналог схемы using\IDisposable на C++ никаких проблем нет. Разве что будет страшненько и громоздко. Но как же тогда песнь о красоте и удобстве деструкторов ?
Здравствуйте, drol, Вы писали:
D>Здравствуйте, k.o., Вы писали:
KO>>Так ведь это и правда очень здорово, в тех случаях, когда освобождение ресурса не приводит к ошибке.
D>Это, конечно, здорово, но ведь даже такая элементарная вещь как, например, закрытие файла может влёгкую выдать ошибку, нуждающуюся в корректной реакции.
KO>>Имхо, таких случаев, всё-таки большинство.
D>Вы уверены ? Ну тогда давайте, перечислите ресурсы, освобождение которых гарантированно корректно и не даёт перехода в fail-состояния.
Тут дело даже не столько в ресурсах, сколько в способе работы с ними.
file data("....");
// пишем что-то в файл
data.flush(); // здесь может вылететь птичка
// автоматический вызов data.~file(), данные либо уже сохранены,
// либо flush выкинул исключение и мы и так получим информацию об ошибке,
// либо нам вобще не удалось сделать всё что нужно, и сохранять нет смысла,
// но закрыть дескриптор файла всё равно нужно.
Смысл в том, что все операции, которые могут завершиться ошибкой лучше делать явно, а задача деструктора, вернуть ресурс туда где взяли. При таком подходе они действительно очень удобны. Иначе мы либо теряем первоначальную ошибку, либо ошибку при завершении работы с ресурсом.
KO>>Ответа, разумеется, нет, с другой стороны, никто не мешает для таких ресурсов использовать другие способы освобождения, позволяющие передать всю нужную информацию наверх.
D>У оппонентов наконец-то начинает возникать понимание Конечно, сделать аналог схемы using\IDisposable на C++ никаких проблем нет. Разве что будет страшненько и громоздко. Но как же тогда песнь о красоте и удобстве деструкторов ?
Я, вроде, особо не оппонировал. Тем не менее, на лямбдах можно вполне себе сделать вменяемый аналог using. Громоздко могло быть раньше, но если нужны все ошибки, оно и в C# не очень красиво будет выглядеть, using\IDisposable тут не помогут.
Здравствуйте, k.o., Вы писали:
KO>Тут дело даже не столько в ресурсах, сколько в способе работы с ними.
Это две стороны одной медали.
KO>
file data("....");
// пишем что-то в файл
data.flush(); // здесь может вылететь птичка
Отлично. То есть Вам потребовалось написать явный вызов. И чем это отличается от явного вызова Dispose() ?
KO>Смысл в том, что все операции, которые могут завершиться ошибкой лучше делать явно, а задача деструктора, вернуть ресурс туда где взяли. KO>При таком подходе они действительно очень удобны. Иначе мы либо теряем первоначальную ошибку, либо ошибку при завершении работы с ресурсом.
Ничего не понял. Хоть ты тресни, но даже простецкий CloseHandle может вернуть ошибку. И я хочу её знать. Что тогда остаётся в коде деструктора ??? И как Вы из него информацию об ошибке собрались извлекать ???
KO>Тем не менее, на лямбдах можно вполне себе сделать вменяемый аналог using.
Угу-угу. И потом ещё ждать десять лет, пока компиляторы C++ научатся их понимать одинаковым образом
KO>оно и в C# не очень красиво будет выглядеть, using\IDisposable тут не помогут.
Здравствуйте, Lloyd, Вы писали:
GZ>>А в случае если мы вылетаем по exception с неизвестным состоянием то мы тоже делаем Commit?
L>Да. Разве это не очевидно?
Такая интерпретация транзакций? Что-то в этом есть. Что-то новое, неизведанное. Кажется ты совешил открытие века.
Здравствуйте, GlebZ, Вы писали:
GZ>>>А в случае если мы вылетаем по exception с неизвестным состоянием то мы тоже делаем Commit?
L>>Да. Разве это не очевидно? GZ>Такая интерпретация транзакций? Что-то в этом есть. Что-то новое, неизведанное. Кажется ты совешил открытие века.
Вообще-то это твое желание сделать Commit внутри Dospose. Ты же утверждал, что это сделать невозможно в существующем синтаксисе, значит для тебя такая возможность — что-то нормальное и желаемое. Я тебе не стал указывать на бредовость такой идеи исключительно из вежливости.
Здравствуйте, Lloyd, Вы писали:
L>Вообще-то это твое желание сделать Commit внутри Dospose. Ты же утверждал, что это сделать невозможно в существующем синтаксисе, значит для тебя такая возможность — что-то нормальное и желаемое. Я тебе не стал указывать на бредовость такой идеи исключительно из вежливости.
Бредовость — это Commit/Rollback как незавершающая часть транзакции. В результате, TransactionScope не полностью отвечает понятию транзакции, что приводит к часто встречающимся ошибкам.
Здравствуйте, GlebZ, Вы писали:
L>>Вообще-то это твое желание сделать Commit внутри Dospose. Ты же утверждал, что это сделать невозможно в существующем синтаксисе, значит для тебя такая возможность — что-то нормальное и желаемое. Я тебе не стал указывать на бредовость такой идеи исключительно из вежливости. GZ>Бредовость — это Commit/Rollback как незавершающая часть транзакции.
Что такое "незавершающая часть транзакции"?
GZ>В результате, TransactionScope не полностью отвечает понятию транзакции, что приводит к часто встречающимся ошибкам.
Не совсем понял, что ты имеешь в виду.
По-моему, это как раз правильно, что commit надо делать явно и в случае если его не было, то автоматически делать rollback. Так TransactionScope и работает.
Здравствуйте, Lloyd, Вы писали:
L>Что такое "незавершающая часть транзакции"? L>Не совсем понял, что ты имеешь в виду. L>По-моему, это как раз правильно, что commit надо делать явно и в случае если его не было, то автоматически делать rollback. Так TransactionScope и работает.
Любая транзакция имеет две фазы. Первая фаза — накопление изменений, вторая фаза — фиксация или откат. Любые изменения после второй фазы обязаны производится в новой транзакции. После явного коммита, любые изменения недопустимы. В данном случае мы имеем две границы: вызов Complete/Rollback и вызов Dispose. В System.Transaction есть классы в которых границей транзакции являются явные команды фиксации/отката, они предназначены для многопоточки и какого нибудь event сценариев и не используюся как using. В случае TransactionScope, который был создан под using и где создаются удобные и читабельные границы транзакции, наличие второй границы является бредом
Здравствуйте, GlebZ, Вы писали:
L>>Что такое "незавершающая часть транзакции"? L>>Не совсем понял, что ты имеешь в виду. L>>По-моему, это как раз правильно, что commit надо делать явно и в случае если его не было, то автоматически делать rollback. Так TransactionScope и работает. GZ>Любая транзакция имеет две фазы. Первая фаза — накопление изменений, вторая фаза — фиксация или откат. Любые изменения после второй фазы обязаны производится в новой транзакции. После явного коммита, любые изменения недопустимы.
Это не так. Изменения допустимы, если транзакция — вложеная.
GZ>В данном случае мы имеем две границы: вызов Complete/Rollback и вызов Dispose. В System.Transaction есть классы в которых границей транзакции являются явные команды фиксации/отката, они предназначены для многопоточки и какого нибудь event сценариев и не используюся как using. В случае TransactionScope, который был создан под using и где создаются удобные и читабельные границы транзакции, наличие второй границы является бредом
Как-то все равно все путанно и непонятен сделанный вывод. Рассказывал одно, потом взял и без какого-либо перехода объявил, что откат в Dispose — бред.