- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
using System;
class TLockCriticalSystemResource : IDisposable
{
public TLockCriticalSystemResource(){Console.WriteLine("Acquire critical system resource");}
public void Dispose(){Console.WriteLine("Release critical system resource");}
public bool Property1{private get{return true;}set{throw new Exception();}}
}
public class Test
{
public static void Main()
{
using (var file = new TLockCriticalSystemResource()
{
Property1=true
})
{
// Делаем чего-то с ресурсом
}
}
}
Ололо. using не даёт гарантию безопасности с точки зрения исключений:
http://ideone.com/nHDIJ
Системный ресурс остался захваченным.
Кстати всегда хотел сделать так:
http://ideone.com/9vnk2
http://ideone.com/2DaQ7
Но c изначальным примером та же трабла:
http://ideone.com/BJWuu
Ресурс считается неинициализированным.
Но мне то что? Я по-старинке пишу:
считая это всё сахаром. Во многих случаях в finally надо еще что-то делать.
Главное не секономить тут строку кода, а красиво это обернуть его в что-то удобное.
А проблема в том, что код выше генерится в такую конструкцию
который станет -
Поэтому и нельзя использовать object initializers вместе с using-ом
Но при этом это компилируется. Ололо. ШАРПАПРОБЛЕМЫ
Если using раскрывается таким образом (я надесь, что не так), то у меня для него плохие новости:
Ресурс снова утёк.
ЗЫ. Abort кагбы не рекомендуется использовать, ибо поток должен завершаться сам. Насколько я помню, они хотели избавится вообще от Abort метода.
Как шарпеи увидять проблему кривых рук в С++, так сразу кричат - крестопроблемы, кресты говно. А как увидят в шарпе - криворук ниасилятор, язык и компилятор шарпа же - невинны.
Что-за двойные стандарты?
И для разных задач можно использовать разные языки, и при этом выбирая нужно знать как о плюсах, так и о минусах. А не просто использовать язык, ибо это "модно".
>я лично так не кричу
MS говорил о том что так делать не рекомендуется.
PS. Я разве где-то что-то кричал на C++?
> кричал на C++
О. Это безблагодатное занятие. С++ вас врятли поймет.
Какие ещё?
>следует использовать CriticalFinalizerObject
Он заставляет обязательно вызывать финализатор во время сборки мусора. Не о каких Dispose и речи не идет. Да и сборка мусора может произойти (и сделает это) через недетерминированное время.
Тогда using будет работать гарантированно так, как задумывался.
Запрещать только из-за того, что недалекие разработчики могут выстрелить себе в ногу... простите.
Ну и нахер оно такое надо?
Коннекшен пул на БД весь занят.
И пользователи ждут неопределенное когда GC освободит хотя бы одно соединение. Шикарно.
>для гарантированного освобождения ресурсов следует использовать
У нормально написанных классов dispose вызывается из деструктора и finalize().
http://reflector.webtropy.com/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/IO/FileStream@cs/1305376/FileStream@cs
См. ~FileStream()
Поддерживаю. "Гарантированное" освобождение ресурса даже через несколько секунд (если коллектор периодически запускается в свободное время, дабы собирать эти потерянные ресурсы) нахуй никому не нужно.
Поподробнее?
И причем тут инициализаторы? Я могу написать и так:
>fluent метод withProp1 кинет исключение.
Гумно прав в основном. В том что в using есть дырка. Инициализаторы здесь ни при чем.
Вот я набросал грубый пример где происходит утечка безо всяких инициализаторов, но с зависимыми ресурсами.
Случай вполне типичный из Connectionа получаем Statement, а из него ResultSet.
http://ideone.com/ZvmIO
Если при освобождении Statementа - упало, соединение не освободили.
>Причина в том что вызов конструктора и dependentResourse
Стоп. Но я же в using все конструкторы написал.
Ни о каких try я не знаю, я ведь специально пишу using, чтоб не писать try.
По-нормальному должно освобождаться.
Там на примере написано во что оно разворачивается. Если бы те кто используют using читали бы это, они бы знали об этом. Просто использовать using незная как он работает в действительности надеясь на "всемогущий фреймворк" как-то глупо.
Почему так, нужно поискать у Липперта. Он рассказывал причину, почему они так сделали.
http://govnokod.ru/11950#comment156393
Конечно кидать исключения из конструкторов и инициализаторов некошерно. Но!
А если у нас там стоит какой-то Wait, который ожидает пока придет Pulse с другого потока - "ресурс освобожден поцоны! "
И тут в наш тред внезапно врывается ThreadInterruptedException.
В частности, этот пост создан по мотивам http://sergeyteplyakov.blogspot.com/2012/05/using.html
Так?
Да это не новость, что Гумно ничего своего не придумывает - как и положено гумну он копипастит чужое.
Так ведь с самого начала было. Только год назад он пастами всё закидывал. Другое дело что теперь до него наконец дошло, что сайт называется ГовноКод. И он постит код. Это большой прогресс между прочим.
Ну и похер что этот код где-то уже был, тут ведь не было. А именно тут ему самое место. Поэтому Гумно и получил плюс.