Здравствуйте, -MyXa-, Вы писали:
MX>Здравствуйте, catBasilio, Вы писали:
B>>собственно сабж. с помощью него в с++ очень удобно организовывать RAII. пример:
MX>Краткое объяснение здесь
про IDisposable я знаю, там нужно явно реализовывать Dispose. если эабыл — то resource leak.
А я же имел ввиду про автоматическое освобождение ресурстов.
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Здравствуйте, catBasilio, Вы писали:
B>про IDisposable я знаю, там нужно явно реализовывать Dispose. если эабыл — то resource leak. B>А я же имел ввиду про автоматическое освобождение ресурстов.
Автоматически только сборка мусора. Если выхотите освободить ресурс в определенный момент времени, то это надо делать явно.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, TK, Вы писали:
TK>Здравствуйте, catBasilio, Вы писали:
B>>про IDisposable я знаю, там нужно явно реализовывать Dispose. если эабыл — то resource leak. B>>А я же имел ввиду про автоматическое освобождение ресурстов.
TK>Автоматически только сборка мусора. Если выхотите освободить ресурс в определенный момент времени, то это надо делать явно.
ясно. Спасибо за рпзъяснения.
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Здравствуйте, -MyXa-, Вы писали:
MX>Здравствуйте, catBasilio, Вы писали:
B>>собственно сабж. с помощью него в с++ очень удобно организовывать RAII. пример:
MX>Краткое объяснение здесь
А вообще, using это каменный век по сравнению с работой деструкторов...
Здравствуйте, HowardLovekraft, Вы писали:
A>>А вообще, using это каменный век по сравнению с работой деструкторов... HL>Толсто троллите.
Он совершенно прав.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
A>>>А вообще, using это каменный век по сравнению с работой деструкторов... HL>>Толсто троллите. WH>Он совершенно прав.
Что не отменяет трололо в сообщении :о)
Ведь утверждать то, что хотя бы для вас является прописной истинной (но не является для собеседника) и не дать хоть какого-то объяснения — чистой вода провокация.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, WolfHound, Вы писали:
A>>>А вообще, using это каменный век по сравнению с работой деструкторов... HL>>Толсто троллите. WH>Он совершенно прав.
А точнее неправ. Иначе придется признать что Dispose является деструктором, что есть подлая ложь. Да и using не идеален. Я бы не отказался от расширения чтобы можно было вызывать не только Dispose. Что-то типа:
Stopwatch t=new Stopwatch();
using(t.Start())//указываем функцию начала
{
...
}(t.Stop());//указываем функцию завершения
Console.WriteLine(t.Elapsed);
Счас на таких задачах приходится Dispose прокси делать.
Здравствуйте, HowardLovekraft, Вы писали:
HL>Здравствуйте, Aviator, Вы писали:
A>>А вообще, using это каменный век по сравнению с работой деструкторов... HL>Толсто троллите.
буду признателен за пример на C# который реализует описаную мной в с++ном коде функциональность. А то пока не понимаю как это элегантно заимплементить.
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Здравствуйте, catBasilio, Вы писали:
A>>>А вообще, using это каменный век по сравнению с работой деструкторов... HL>>Толсто троллите.
B>буду признателен за пример на C# который реализует описаную мной в с++ном коде функциональность. А то пока не понимаю как это элегантно заимплементить.
Вы примеры про использование IDisposable посмотреть затруднились
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, catBasilio, Вы писали:
B>буду признателен за пример на C# который реализует описаную мной в с++ном коде функциональность
А вы приведете пример пример на C#, в котором выполняется явное уничтожение экземпляра reference-типа?
Re[3]: есть ли в С# аналог std::auto_ptr ?
От:
Аноним
Дата:
08.06.11 13:18
Оценка:
Здравствуйте, Aviator, Вы писали:
A>Здравствуйте, -MyXa-, Вы писали:
MX>>Здравствуйте, catBasilio, Вы писали:
B>>>собственно сабж. с помощью него в с++ очень удобно организовывать RAII. пример:
MX>>Краткое объяснение здесь A>А вообще, using это каменный век по сравнению с работой деструкторов...
а пояснить примером можете?
желатеельно в сравнении
Здравствуйте, -MyXa-, Вы писали:
MX>Пример в первом сообщении этой ветки.
Отлично. Тогда покажите как на таком материале сделать обработку исключительных ситуаций\ошибок возникающих в ходе освобождения ресурсов. Для конкретности, пускай наш ресурс это распределённая транзакция
Здравствуйте, GlebZ, Вы писали:
GZ>Да и using не идеален. Я бы не отказался от расширения чтобы можно было вызывать не только Dispose. Что-то типа: GZ>
GZ>Stopwatch t=new Stopwatch();
GZ>using(t.Start())//указываем функцию начала
GZ>{
GZ>...
GZ>}(t.Stop());//указываем функцию завершения
GZ>Console.WriteLine(t.Elapsed);
GZ>
GZ>Счас на таких задачах приходится Dispose прокси делать.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, GlebZ, Вы писали:
GZ>>Да и using не идеален. Я бы не отказался от расширения чтобы можно было вызывать не только Dispose. Что-то типа: GZ>>
GZ>>Stopwatch t=new Stopwatch();
GZ>>using(t.Start())//указываем функцию начала
GZ>>{
GZ>>...
GZ>>}(t.Stop());//указываем функцию завершения
GZ>>Console.WriteLine(t.Elapsed);
GZ>>
GZ>>Счас на таких задачах приходится Dispose прокси делать.
L>
Здравствуйте, drol, Вы писали:
D>Здравствуйте, -MyXa-, Вы писали:
MX>>Пример в первом сообщении этой ветки.
D>Отлично. Тогда покажите как на таком материале сделать обработку исключительных ситуаций\ошибок возникающих в ходе освобождения ресурсов. Для конкретности, пускай наш ресурс это распределённая транзакция
Общее правило с++ деструкторы — не могут кидать исключения. Так что с обработкой ошибок\исключений там все замечательно.
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Здравствуйте, catBasilio, Вы писали:
B>Общее правило с++ деструкторы — не могут кидать исключения.
Нет такого правила в "Стандарте" В C++ деструкторы вполне себе могут бросать исключения. Просто потенциально возможные последствия оных "бросков" не устраивают пользователей языка
B>Так что с обработкой ошибок\исключений там все замечательно.
Ну как же "замечательно", если по Вашим словам выходит, что она невозможна ??? Тогда как нормальная работа с любым нетривиальным ресурсом, повторяю пример — распределённая транзакция, нуждается в этих механизмах.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Aviator, Вы писали:
A>>Здравствуйте, -MyXa-, Вы писали:
MX>>>Здравствуйте, catBasilio, Вы писали:
B>>>>собственно сабж. с помощью него в с++ очень удобно организовывать RAII. пример:
MX>>>Краткое объяснение здесь A>>А вообще, using это каменный век по сравнению с работой деструкторов...
А>а пояснить примером можете? А>желатеельно в сравнении
Не хочу ввязываться в дискуссию, представьте на досуге что будет в c#, если ресурс A агрегирует ресурс B, который в свою очередь агрегирует С. Ресурсы B и C надо явно освободить по освобождению A.
Здравствуйте, Aviator, Вы писали:
A>Не хочу ввязываться в дискуссию, представьте на досуге что будет в c#, если ресурс A агрегирует ресурс B, который в свою очередь агрегирует С. Ресурсы B и C надо явно освободить по освобождению A.
А теперь представьте, что в процессе освобождения ресурса C произошла ошибка, и информацию об оной нужно отправить дальше по callstack'у тем, кто знает что в этом случае делать.
Здравствуйте, drol, Вы писали:
B>>Общее правило с++ деструкторы — не могут кидать исключения. D>Нет такого правила в "Стандарте" В C++ деструкторы вполне себе могут бросать исключения. Просто потенциально возможные последствия оных "бросков" не устраивают пользователей языка
ISO/IEC 14882
Second edition 2003-10-15
15.2 Constructors and destructors [except.ctor], абзац 3
The process of calling destructors for automatic objects constructed on the path from a try block to a
throw-expression is called “stack unwinding.” [Note: If a destructor called during stack unwinding exits
with an exception, terminate is called (15.5.1). So destructors should generally catch exceptions and
not let them propagate out of the destructor. —end note]
То есть в стандарте явно запрещено выбрасывание чего-либо из деструктора.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, drol, Вы писали:
_FR>>То есть в стандарте явно запрещено выбрасывание чего-либо из деструктора.
D>Где Вы это увидели ??? "should generally", да ещё и в каком-то там примечании это определённо не запрет.
Что значит "где"?
Help will always be given at Hogwarts to those who ask for it.
L>>>Зачем что-то еще?
B>>в с++ за такой код полагается руки отрывать.
L>Во-первых, в с++ нет finally. L>А во-вторых, вопрос о том, чем вариант GlebZ-а лучше варианта с finally.
ничем не лучше. Оба кривые.
В продакшин коде может сложиться ситуация, когда между try и finally будет помещено много кода разными коммитерами в разное время. И очень высока вероятность, что кто-нибудь просто по невнимательности забудет написать в finally освобождение ресурса.
код с using немного лучше, но это только для блока. непонятно как это юзать для мемберов класса. Кроме того надо не забыть в Dispose явно освободить ресурс. Что чревато, как и в первом случае.
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Здравствуйте, _FRED_, Вы писали:
D>>Где Вы это увидели ??? "should generally", да ещё и в каком-то там примечании это определённо не запрет.
_FR>Что значит "где"?
Э-э-э... Вам объяснить как переводится выражение с "should generally" ? И чем примечание отличается от собственно текста пункта "Стандарта" ?
Здравствуйте, catBasilio, Вы писали:
B>>>в с++ за такой код полагается руки отрывать.
L>>Во-первых, в с++ нет finally. L>>А во-вторых, вопрос о том, чем вариант GlebZ-а лучше варианта с finally.
B>ничем не лучше. Оба кривые. B>В продакшин коде может сложиться ситуация, когда между try и finally будет помещено много кода разными коммитерами в разное время. И очень высока вероятность, что кто-нибудь просто по невнимательности забудет написать в finally освобождение ресурса.
А в с++ вероятность того, что кто-то не напишет нужную обертку, видимо нулевая?
B>код с using немного лучше, но это только для блока. непонятно как это юзать для мемберов класса. Кроме того надо не забыть в Dispose явно освободить ресурс. Что чревато, как и в первом случае.
Вы зря не посмотрели код GlebZ. Там, гм, не совсем using.
Здравствуйте, drol, Вы писали:
D>Здравствуйте, _FRED_, Вы писали:
_FR>>То есть в стандарте явно запрещено выбрасывание чего-либо из деструктора.
D>Где Вы это увидели ??? "should generally", да ещё и в каком-то там примечании это определённо не запрет.
исключение вышедшее за границы деструктора — результат вызов terminate() и завершение программы.
15.5.1 The std::terminate() function
1
[except.terminate]
In the following situations exception handling must be abandoned for less subtle error handling techniques:
— when the exception handling mechanism, after completing evaluation of the expression to be thrown but before
the exception is caught (15.1), calls a user function that exits via an uncaught exception,140)
— when the exception handling mechanism cannot find a handler for a thrown exception (15.3), or
— when the destruction of an object during stack unwinding (15.2) exits using an exception, or
и еще
15.3
Handling an exception
The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is
called “stack unwinding.” [ Note: If a destructor called during stack unwinding exits with an exception, std::termin-
ate is called (15.5.1). So destructors should generally catch exceptions and not let them propagate out of the destructor.
— end note ]
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Здравствуйте, drol, Вы писали:
D>Здравствуйте, catBasilio, Вы писали:
B>>исключение вышедшее за границы деструктора — результат вызов terminate() и завершение программы.
D>Ничего подобного. terminate() будет только если исключение выброшено из деструктора в ходе раскрутки стека. Во всех остальных случаях проблем нет.
Дык дело в том, что "правильного" метода, для определения, был ли вызван деструктор вызван в процессе расскрутки после выброса исключения, или в "обычном" режиме, — НЕТ.
Здравствуйте, Aviator, Вы писали:
A>А вообще, using это каменный век по сравнению с работой деструкторов...
А вообще, красное — холоднее, чем дырявое...
Ну а по теме: пишешь на шарпе после на плюсов — не хватает дестукторов, оператора->, а так-же шаблонов. При пеходе в другом направлении, не хватает вообще ничего. А вот если писать параллельно и на том и на том, в зависимости от задач, имея определённый опыт, то всё пучком
Здравствуйте, Angler, Вы писали:
A>Дык дело в том, что "правильного" метода, для определения, был ли вызван деструктор вызван в процессе расскрутки после выброса исключения, или в "обычном" режиме, — НЕТ.
Наличие\отсутствие такого метода — обсуждаемому вопросу совершенно ортогонально. Корректная C++ программа, реально бросающая исключение из деструктора и не финиширующая в этой связи через terminate() и прочие нездоровые вещи, всё равно возможна.
Здравствуйте, drol, Вы писали:
D>Наличие\отсутствие такого метода — обсуждаемому вопросу совершенно ортогонально. Корректная C++ программа, реально бросающая исключение из деструктора и не финиширующая в этой связи через terminate() и прочие нездоровые вещи, всё равно возможна.
Возможность существования никто и не отрицает. Правда на все такие программы накладывается одно жёсткое требование — в деструкторе необходимо знать контекст использования обьекта. Соответвственно и в месте использования такого обьекта необходимо знать, с каким "гадом" имеешь дело.
Этот вопрос перетирался на плюсовом форуме n-раз.
Здравствуйте, Angler, Вы писали:
A>Возможность существования никто и не отрицает.
Так зачем Вы тогда пытались заболтать тему, ежели согласны с ложностью выдвинутого "конкурирующей организацией" тезиса
*Вопрос риторический
С этим разобрались, возвращаемся к исходной теме: как всё-таки оппоненты using\IDisposable предлагают решать дежурную задачу проноса информации об исключительных ситуациях, возникших при освобождении ресурса, в случае цепочки автоматических вызовов деструкторов ?
Здравствуйте, drol, Вы писали:
D>>>Где Вы это увидели ??? "should generally", да ещё и в каком-то там примечании это определённо не запрет. _FR>>Что значит "где"? D>Э-э-э... Вам объяснить как переводится выражение с "should generally" ? И чем примечание отличается от собственно текста пункта "Стандарта" ?
Согласен, с "явно запрещено" я переборщил.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, drol, Вы писали:
D>Здравствуйте, catBasilio, Вы писали:
B>>исключение вышедшее за границы деструктора — результат вызов terminate() и завершение программы.
D>Ничего подобного. terminate() будет только если исключение выброшено из деструктора в ходе раскрутки стека. Во всех остальных случаях проблем нет.
Пример остальных случаев пожалуйста.
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Здравствуйте, drol, Вы писали:
D>Здравствуйте, Aviator, Вы писали:
A>>Не хочу ввязываться в дискуссию, представьте на досуге что будет в c#, если ресурс A агрегирует ресурс B, который в свою очередь агрегирует С. Ресурсы B и C надо явно освободить по освобождению A.
D>А теперь представьте, что в процессе освобождения ресурса C произошла ошибка, и информацию об оной нужно отправить дальше по callstack'у тем, кто знает что в этом случае делать.
И что вы будете делать с ошибкой при освобождении ресурса выше по стеку если не секрет?
ЗЫ При исключении из диспоуза вас не смущает, что часть ресурсов корректно освобождена а часть повисла в непонятном состоянии?
Здравствуйте, Lloyd, Вы писали:
L>Зачем что-то еще?
Дядька — using тоже синтаксический сахар finally с IDisposable. Вопрос другой, что выглядит лучше и понятней, поэтому используют именно его, а не finally. Я широко использую using без освобождения ресурсов. В этом случае прекрасно видны границы работы функций. Но для этого приходится генерить прокси классы.
Здравствуйте, GlebZ, Вы писали:
GZ>Дядька — using тоже синтаксический сахар finally с IDisposable. Вопрос другой, что выглядит лучше и понятней, поэтому используют именно его, а не finally. Я широко использую using без освобождения ресурсов. В этом случае прекрасно видны границы работы функций. Но для этого приходится генерить прокси классы.
Я использую хелпер.
class Scope: IDisposable
{
private readonly Action onDispose;
public Scope(Action onDispose)
{
this.onDispose = onDispose;
}
public void Dispose()
{
onDispose();
}
}
// пример использованияpublic IDisposable InTransaction(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted)
{
BeginTransaction(isolationLevel);
return new Scope(() =>
{
if (Transaction != null)
CommitTransaction();
});
}
void foo()
{
using (InTransaction())
{
// some logic
}
}
Здравствуйте, catBasilio, Вы писали:
B>Здравствуйте, drol, Вы писали:
D>>Здравствуйте, catBasilio, Вы писали:
B>>>исключение вышедшее за границы деструктора — результат вызов terminate() и завершение программы.
D>>Ничего подобного. terminate() будет только если исключение выброшено из деструктора в ходе раскрутки стека. Во всех остальных случаях проблем нет.
B>Пример остальных случаев пожалуйста.
Здравствуйте, drol, Вы писали:
D>Здравствуйте, Angler, Вы писали:
A>>Возможность существования никто и не отрицает.
D>Так зачем Вы тогда пытались заболтать тему, ежели согласны с ложностью выдвинутого "конкурирующей организацией" тезиса
Возможность то есть, но за наличие трывают руки(как вариант — отрезаешь себе со временем уши). Такой себе сферический конь в вакууме..
Здравствуйте, drol, Вы писали:
D>Здравствуйте, Aviator, Вы писали:
A>>Не хочу ввязываться в дискуссию, представьте на досуге что будет в c#, если ресурс A агрегирует ресурс B, который в свою очередь агрегирует С. Ресурсы B и C надо явно освободить по освобождению A.
D>А теперь представьте, что в процессе освобождения ресурса C произошла ошибка, и информацию об оной нужно отправить дальше по callstack'у тем, кто знает что в этом случае делать.
а что делать с ошибкой, которая привела к вызову Dispose и информацию о которой тоже нужно отправить дальше?
Здравствуйте, GlebZ, Вы писали:
L>>Зачем что-то еще? GZ>Дядька — using тоже синтаксический сахар finally с IDisposable.
Спасибо, мальчик. Ты решил поиграть в капитана? Похвально.
GZ>Вопрос другой, что выглядит лучше и понятней, поэтому используют именно его, а не finally.
Уверяю тебя, тот код, котрый ты привел точно не используют, т.к. он даже не скомпилится.
GZ>Я широко использую using без освобождения ресурсов. В этом случае прекрасно видны границы работы функций. Но для этого приходится генерить прокси классы.
Тот вариант, что ты привел — весьма сомнителен. Если уж хочется непременно использовать using, то можно придумать более понятные варианты даже не выходя за рамки существующего языка.
Здравствуйте, HowardLovekraft, Вы писали:
HL>Здравствуйте, Aviator, Вы писали:
A>>А вообще, using это каменный век по сравнению с работой деструкторов... HL>Толсто троллите.
Это крик души
Здравствуйте, Aviator, Вы писали:
A>И что вы будете делать с ошибкой при освобождении ресурса выше по стеку если не секрет?
Что захочу, то и сделаю. В рамках примера с распределённой транзакцией — можно просто сразу повторить транзакцию, можно зашедулить повторение через таймаут, можно написать в лог, можно спросить пользователя, можно проанализировать причину отказа и выдать рекомендации и т.д., и т.п., и даже всё сразу
A>ЗЫ При исключении из диспоуза вас не смущает, что часть ресурсов корректно освобождена а часть повисла в непонятном состоянии?
Ничто и нигде не повисло — catch\finally-блоки обо всём позаботятся. В отличии от деструкторов С++ им ведь доступна вся информация о ситуации.
Здравствуйте, drol, Вы писали:
D>Здравствуйте, Aviator, Вы писали:
A>>И что вы будете делать с ошибкой при освобождении ресурса выше по стеку если не секрет?
D>Что захочу, то и сделаю. В рамках примера с распределённой транзакцией — можно просто сразу повторить транзакцию, можно зашедулить повторение через таймаут, можно написать в лог, можно спросить пользователя, можно проанализировать причину отказа и выдать рекомендации и т.д., и т.п., и даже всё сразу
Проанализировать причину отказа при освобождении ресурса? Что курим? Может мессаджбокс ещё юзеру покажешь "Извини, не могу освободить ресурс" ?
A>>ЗЫ При исключении из диспоуза вас не смущает, что часть ресурсов корректно освобождена а часть повисла в непонятном состоянии?
D>Ничто и нигде не повисло — catch\finally-блоки обо всём позаботятся. В отличии от деструкторов С++ им ведь доступна вся информация о ситуации.
Что им доступно, ты не освободил половину ресурсов, половина уже грохнута, причём последний вызов завершился с исключением. Что будет при убивании оставшейся половины — одному богу известно и будет отлично проглочено при вызове финализатора.
Здравствуйте, Aviator, Вы писали:
A>Проанализировать причину отказа при освобождении ресурса?
Ага. Например, если транзакция не прошла, и я вижу в цепочках исключений какой-нибудь SocketClosedByTimeoutException, то можно проверить состояние сети, видимость сервера и т.п. И, соответственно, много чего интеллектуального сделать на эту тему — поставить мониторинг на восстановление связи, зашедулить повтор транзакции и т.д.
A>Что курим?
Да уж явно не то что освободители ресурсов в деструкторах глотающие все ошибки
A>Может мессаджбокс ещё юзеру покажешь "Извини, не могу освободить ресурс" ?
Если есть разумный use case с UI — конечно же покажу.
A>Что им доступно, ты не освободил половину ресурсов, половина уже грохнута, причём последний вызов завершился с исключением.
Вот именно что с исключением. А нормальное исключение явно говорит в чём проблема.
A>Что будет при убивании оставшейся половины — одному богу известно
Насчёт бога не знаю, а вот мне обычно прекрасно известно что может быть. Программные системы они того — детерминированные, знаете ли.
A>и будет отлично проглочено при вызове финализатора.
Финализатор здесь совершенно не при делах, бо он вызывается в случае, когда информация об ошибочных ситуациях как раз не нужна. И деструкторы C++ как раз являются аналогом финализатора в этом плане.
Здравствуйте, Aviator, Вы писали:
A>То что в при исключении не все диспоузы отработают
С каких это ??? В общем случае все finally-блоки по пути всегда исполняются. Если нужна более сложная схема — пожалуйста, можно явные catch'и понаписать, и логику освобождения какую душе угодно.
Здравствуйте, drol, Вы писали:
D>Здравствуйте, Aviator, Вы писали:
A>>То что в при исключении не все диспоузы отработают
D>С каких это ??? В общем случае все finally-блоки по пути всегда исполняются. Если нужна более сложная схема — пожалуйста, можно явные catch'и понаписать, и логику освобождения какую душе угодно.
Здравствуйте, Lloyd, Вы писали:
L>Спасибо, мальчик. Ты решил поиграть в капитана? Похвально.
Ты что, обиделся? Это просто у меня такое выражение. Ничего личного, и никого не хотел оскорбить.
GZ>>Вопрос другой, что выглядит лучше и понятней, поэтому используют именно его, а не finally. L>Уверяю тебя, тот код, котрый ты привел точно не используют, т.к. он даже не скомпилится.
Тот код который я привел как не является юзингом, так и не являеся кодом. Это просто пример.
И вообще, я говорю о двух недостатках using, который ограничивает его использование:
1. Привязка к IDisposable
2. Привязка к finally.
По первой понятно из кода. По второй, я грешен не указал, — мы не имеем информации как мы пролетаем по finally, через exception или нормальным исполнением.
GZ>>Я широко использую using без освобождения ресурсов. В этом случае прекрасно видны границы работы функций. Но для этого приходится генерить прокси классы. L>Тот вариант, что ты привел — весьма сомнителен. Если уж хочется непременно использовать using, то можно придумать более понятные варианты даже не выходя за рамки существующего языка.
Ну да. Например: этот
. Я счас присмотрелся, пример интересный, но неправильный. В случае exception транзакция подтвердится.
Попробуй напиши правильно, чтобы можно было делать а ля ScopeTransaction но без явного и бесполезного указания Commit.
Здравствуйте, Aviator, Вы писали:
A>У тебя из finally вылетает исключение
Да без разницы откуда оно вылетает — finally-блоки поэтому и finally, бо в нормальном потоке исполнения они отрабатывают в независимости от того что и откуда вылетело. Если в finally нужна логика в которой возможны свои исключения — ну так пишите try\catch и ловите их там.
Здравствуйте, GlebZ, Вы писали:
GZ>>>Вопрос другой, что выглядит лучше и понятней, поэтому используют именно его, а не finally. L>>Уверяю тебя, тот код, котрый ты привел точно не используют, т.к. он даже не скомпилится. GZ>Тот код который я привел как не является юзингом, так и не являеся кодом. Это просто пример.
О том и речь. Потому говорить "используют именно его" некорректно.
L>>Тот вариант, что ты привел — весьма сомнителен. Если уж хочется непременно использовать using, то можно придумать более понятные варианты даже не выходя за рамки существующего языка. GZ>Ну да. Например: этот
. Я счас присмотрелся, пример интересный, но неправильный. В случае exception транзакция подтвердится. GZ>Попробуй напиши правильно, чтобы можно было делать а ля ScopeTransaction но без явного и бесполезного указания Commit.
Там просто не надо было использовать using, он там не нужен.
Здравствуйте, 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 — бред.
Здравствуйте, Lloyd, Вы писали:
L>Это не так. Изменения допустимы, если транзакция — вложеная.
Нет. Если транзакция вложенная (и то, там много своих определений), то все остается в силе. Создавай другую вложенную транзакцию.
L>Как-то все равно все путанно и непонятен сделанный вывод. Рассказывал одно, потом взял и без какого-либо перехода объявил, что откат в Dispose — бред.
Неверно. Я утверждал что отсутвие Complete в Dispose при нормальном выполнении кода — бред.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Lloyd, Вы писали:
L>>Как-то все равно все путанно и непонятен сделанный вывод. Рассказывал одно, потом взял и без какого-либо перехода объявил, что откат в Dispose — бред. GZ>Неверно. Я утверждал что отсутвие Complete в Dispose при нормальном выполнении кода — бред.
А как в Dispose узнать, было ли выполнение кода нормальным или нет?
Здравствуйте, GlebZ, Вы писали:
L>>Это не так. Изменения допустимы, если транзакция — вложеная. GZ>Нет. Если транзакция вложенная (и то, там много своих определений), то все остается в силе. Создавай другую вложенную транзакцию.
Зачем? Они и так будут в объемлющей транзакции.
L>>Как-то все равно все путанно и непонятен сделанный вывод. Рассказывал одно, потом взял и без какого-либо перехода объявил, что откат в Dispose — бред. GZ>Неверно. Я утверждал что отсутвие Complete в Dispose при нормальном выполнении кода — бред.
Но даже и этот вывод остался непонятен.
По-моему, если пользователь явно задал границы транзакции с помощью TransactionScope, то явно же ее и должен закоммитить. Если ты не закоммитил, то это должно трактоваться как ошибка и сделанные изменения должны быть откачены.
По мне, так вполне логичный подход.
Здравствуйте, samius, Вы писали:
L>>>Как-то все равно все путанно и непонятен сделанный вывод. Рассказывал одно, потом взял и без какого-либо перехода объявил, что откат в Dispose — бред. GZ>>Неверно. Я утверждал что отсутвие Complete в Dispose при нормальном выполнении кода — бред. S>А как в Dispose узнать, было ли выполнение кода нормальным или нет?
Руки бы поотрывал!
public void Dispose()
{
if (Marshal.GetExceptionCode()==0)
Console.WriteLine("Completed Successfully!");
else
Console.WriteLine("Exception!");
}
Здравствуйте, Lloyd, Вы писали:
L>>>Это не так. Изменения допустимы, если транзакция — вложеная. GZ>>Нет. Если транзакция вложенная (и то, там много своих определений), то все остается в силе. Создавай другую вложенную транзакцию. L>Зачем? Они и так будут в объемлющей транзакции.
Для того чтобы объемлющая транзакция могла зафиксироваться, каждая вложенная транзакция должны вызвать команду commit.
L>>>Как-то все равно все путанно и непонятен сделанный вывод. Рассказывал одно, потом взял и без какого-либо перехода объявил, что откат в Dispose — бред. GZ>>Неверно. Я утверждал что отсутвие Complete в Dispose при нормальном выполнении кода — бред.
L>Но даже и этот вывод остался непонятен. L>По-моему, если пользователь явно задал границы транзакции с помощью TransactionScope, то явно же ее и должен закоммитить. Если ты не закоммитил, то это должно трактоваться как ошибка и сделанные изменения должны быть откачены. L>По мне, так вполне логичный подход.
А по моему нет. В случае если код выполнился, и не было вызвано исключение, то транзакция должны быть закомичена. В случае если код сгенерил исключение, то безусловно роллбек.
Здравствуйте, GlebZ, Вы писали:
GZ>>>Нет. Если транзакция вложенная (и то, там много своих определений), то все остается в силе. Создавай другую вложенную транзакцию. L>>Зачем? Они и так будут в объемлющей транзакции. GZ>Для того чтобы объемлющая транзакция могла зафиксироваться, каждая вложенная транзакция должны вызвать команду commit.
Да, но это не отвечает на заданный вопрос.
L>>По-моему, если пользователь явно задал границы транзакции с помощью TransactionScope, то явно же ее и должен закоммитить. Если ты не закоммитил, то это должно трактоваться как ошибка и сделанные изменения должны быть откачены. L>>По мне, так вполне логичный подход. GZ>А по моему нет. В случае если код выполнился, и не было вызвано исключение, то транзакция должны быть закомичена. В случае если код сгенерил исключение, то безусловно роллбек.
Нелогично. Раз уж ты объявил скоуп, то и коммить его.
Хотя это уже вопрос вкуса.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, samius, Вы писали:
S>>А как в Dispose узнать, было ли выполнение кода нормальным или нет?
_FR>Руки бы поотрывал! _FR>
_FR> public void Dispose()
_FR> {
_FR> if (Marshal.GetExceptionCode()==0)
_FR> Console.WriteLine("Completed Successfully!");
_FR> else
_FR> Console.WriteLine("Exception!");
_FR> }
_FR>
Здравствуйте, GlebZ, Вы писали:
GZ>А точнее неправ. Иначе придется признать что Dispose является деструктором, что есть подлая ложь. Да и using не идеален. Я бы не отказался от расширения чтобы можно было вызывать не только Dispose. Что-то типа: GZ>
GZ>Stopwatch t=new Stopwatch();
GZ>using(t.Start())//указываем функцию начала
GZ>{
GZ>...
GZ>}(t.Stop());//указываем функцию завершения
GZ>Console.WriteLine(t.Elapsed);
GZ>
GZ>Счас на таких задачах приходится Dispose прокси делать.
В RX (и не только в нем) есть такой вариант:
var t = Stopwatch.StartNew();
using (Disposable.Create(t.Stop))
{
...
}
Console.WriteLine(t.Elapsed);
... << RSDN@Home 1.2.0 alpha 5 rev. 1495 on Windows 7 6.1.7601.65536>>
Здравствуйте, drol, Вы писали:
D>Здравствуйте, k.o., Вы писали:
KO>>Тут дело даже не столько в ресурсах, сколько в способе работы с ними.
D>Это две стороны одной медали.
KO>>
D>file data("....");
D>// пишем что-то в файл
D>data.flush(); // здесь может вылететь птичка
D>
D>Отлично. То есть Вам потребовалось написать явный вызов. И чем это отличается от явного вызова Dispose() ?
Тем, что, flush не закрывает файл и у нас по прежнему есть неявный вызов деструктора.
KO>>Смысл в том, что все операции, которые могут завершиться ошибкой лучше делать явно, а задача деструктора, вернуть ресурс туда где взяли. KO>>При таком подходе они действительно очень удобны. Иначе мы либо теряем первоначальную ошибку, либо ошибку при завершении работы с ресурсом.
D>Ничего не понял. Хоть ты тресни, но даже простецкий CloseHandle может вернуть ошибку. И я хочу её знать. Что тогда остаётся в коде деструктора ??? И как Вы из него информацию об ошибке собрались извлекать ???
Проверять CloseHandle для файлов, это, пожалуй, черезчур параноидально. Кроме того, если он всё-таки вернёт ошибку, разумнее, наверно, не исключение кидать, а поскорее умереть, сохранив перед этим crashdump.
KO>>Тем не менее, на лямбдах можно вполне себе сделать вменяемый аналог using.
D>Угу-угу. И потом ещё ждать десять лет, пока компиляторы C++ научатся их понимать одинаковым образом
А можно, подробнее, какие несовместимости в понимании лямбд есть у современных компиляторов C++?
KO>>оно и в C# не очень красиво будет выглядеть, using\IDisposable тут не помогут.
D>В C# тоже есть лямбды, и много чего ещё впридачу
Ну, т.е. тоже делать свой using с шахматами и поэтессами?
Здравствуйте, k.o., Вы писали:
D>>Отлично. То есть Вам потребовалось написать явный вызов. И чем это отличается от явного вызова Dispose() ?
KO>Тем, что, flush не закрывает файл и у нас по прежнему есть неявный вызов деструктора.
То есть ничем. Я Вас правильно понял ?
KO>Проверять CloseHandle для файлов, это, пожалуй, черезчур параноидально.
Сценариев предостаточно. То что Вы их не видите — ну да, кто-то вон вообще всю жизнь лабает г-сайты на php
KO>Кроме того, если он всё-таки вернёт ошибку, разумнее, наверно, не исключение кидать, а поскорее умереть, сохранив перед этим crashdump.
Не надо вилять — отвечайте на вопрос прямо.
KO>А можно, подробнее, какие несовместимости в понимании лямбд есть у современных компиляторов C++?
Не знаю. А вот что знаю, так это то, что нового стандарта до сих пор нет Помимо этого я прекрасно помню epic fail'ы по части поддержки шаблонов и реализации стандартной библиотеки. И посему лично у меня нет никаких оснований предполагать безболезненное внедрение в C++ и вышеупомянутых новых фич.
KO>Ну, т.е. тоже делать свой using с шахматами и поэтессами?
Ну и зачем Вы это написали ? Какой Ваш тезис-то ? Или так побалакать ?
Здравствуйте, drol, Вы писали:
D>Здравствуйте, k.o., Вы писали:
D>>>Отлично. То есть Вам потребовалось написать явный вызов. И чем это отличается от явного вызова Dispose() ?
KO>>Тем, что, flush не закрывает файл и у нас по прежнему есть неявный вызов деструктора.
D>То есть ничем. Я Вас правильно понял ?
Видимо нет, но что-то у меня появились сомнения в желании понять.
KO>>Проверять CloseHandle для файлов, это, пожалуй, черезчур параноидально.
D>Сценариев предостаточно. То что Вы их не видите — ну да, кто-то вон вообще всю жизнь лабает г-сайты на php
Ну так опиши эти сценарии, мне правда интересно.
KO>>Кроме того, если он всё-таки вернёт ошибку, разумнее, наверно, не исключение кидать, а поскорее умереть, сохранив перед этим crashdump.
D>Не надо вилять — отвечайте на вопрос прямо.
На какой вопрос я не ответил? Что должно быть в деструкторе? Если действительно хочется получать информацию об ошибках CloseHandle, то вызов кода, сохраняющего crashdump и прибивающего приложение, возможно с записью в лог и предложением перезапустить приложение.
KO>>А можно, подробнее, какие несовместимости в понимании лямбд есть у современных компиляторов C++?
D>Не знаю. А вот что знаю, так это то, что нового стандарта до сих пор нет Помимо этого я прекрасно помню epic fail'ы по части поддержки шаблонов и реализации стандартной библиотеки. И посему лично у меня нет никаких оснований предполагать безболезненное внедрение в C++ и вышеупомянутых новых фич.
Т.е. это всё домыслы. Современные компиляторы, в т.ч. gcc, компилятор от MS, icc, достаточно давно и достаточно хорошо поддерживают лямбды. Даже если случится чудо и новый стандарт не выйдет, эту поддержку уже не выкинут, чтобы не ломать существующий код.
KO>>Ну, т.е. тоже делать свой using с шахматами и поэтессами?
D>Ну и зачем Вы это написали ? Какой Ваш тезис-то ? Или так побалакать ?
Мне было интересно как ты видишь работу с ресурсами в C#. Если использовать обычный using, то при броске исключения из Dispose потеряется исключение, которое могло быть кинуто в блоке using. Если использовать try/catch/finally и явный вызов Dispose, код получится не самый красивый, можно сделать свой using, может быть, можно ещё что-то сделать. Какой вариант ты предлагаешь?
[offtopic]
Что-то мне начинает казаться, у тебя вообще нет желания конструктивную беседу вести.
[/offtopic]