- 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
Системный ресурс остался захваченным.
bormand 17.10.2012 20:03 # +6
3.14159265 17.10.2012 20:11 # +1
Кстати всегда хотел сделать так:
http://ideone.com/9vnk2
3.14159265 17.10.2012 20:33 # 0
http://ideone.com/2DaQ7
Но c изначальным примером та же трабла:
http://ideone.com/BJWuu
Ресурс считается неинициализированным.
Но мне то что? Я по-старинке пишу:
считая это всё сахаром. Во многих случаях в finally надо еще что-то делать.
Главное не секономить тут строку кода, а красиво это обернуть его в что-то удобное.
vse_govno 17.10.2012 20:20 # +1
phoenixx 17.10.2012 22:08 # +2
А проблема в том, что код выше генерится в такую конструкцию
который станет -
Поэтому и нельзя использовать object initializers вместе с using-ом
LispGovno 17.10.2012 22:15 # +2
Но при этом это компилируется. Ололо. ШАРПАПРОБЛЕМЫ
Если using раскрывается таким образом (я надесь, что не так), то у меня для него плохие новости:
Ресурс снова утёк.
phoenixx 17.10.2012 22:17 # 0
ЗЫ. Abort кагбы не рекомендуется использовать, ибо поток должен завершаться сам. Насколько я помню, они хотели избавится вообще от Abort метода.
LispGovno 17.10.2012 22:27 # +3
Как шарпеи увидять проблему кривых рук в С++, так сразу кричат - крестопроблемы, кресты говно. А как увидят в шарпе - криворук ниасилятор, язык и компилятор шарпа же - невинны.
Что-за двойные стандарты?
phoenixx 17.10.2012 22:32 # 0
И для разных задач можно использовать разные языки, и при этом выбирая нужно знать как о плюсах, так и о минусах. А не просто использовать язык, ибо это "модно".
LispGovno 17.10.2012 22:45 # +1
>я лично так не кричу
phoenixx 17.10.2012 22:48 # 0
MS говорил о том что так делать не рекомендуется.
PS. Я разве где-то что-то кричал на C++?
LispGovno 17.10.2012 22:51 # +1
> кричал на C++
О. Это безблагодатное занятие. С++ вас врятли поймет.
absolut 18.10.2012 07:23 # +3
vse_govno 17.10.2012 23:32 # +1
LispGovno 17.10.2012 23:52 # +1
Какие ещё?
>следует использовать CriticalFinalizerObject
Он заставляет обязательно вызывать финализатор во время сборки мусора. Не о каких Dispose и речи не идет. Да и сборка мусора может произойти (и сделает это) через недетерминированное время.
vse_govno 17.10.2012 23:59 # 0
LispGovno 18.10.2012 00:03 # 0
vse_govno 18.10.2012 00:08 # +1
Тогда using будет работать гарантированно так, как задумывался.
LispGovno 18.10.2012 00:38 # 0
vse_govno 18.10.2012 00:41 # +1
Запрещать только из-за того, что недалекие разработчики могут выстрелить себе в ногу... простите.
3.14159265 18.10.2012 13:39 # +1
Ну и нахер оно такое надо?
Коннекшен пул на БД весь занят.
И пользователи ждут неопределенное когда 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()
bormand 18.10.2012 13:52 # +3
Поддерживаю. "Гарантированное" освобождение ресурса даже через несколько секунд (если коллектор периодически запускается в свободное время, дабы собирать эти потерянные ресурсы) нахуй никому не нужно.
LispGovno 17.10.2012 23:56 # −1
Поподробнее?
vse_govno 18.10.2012 00:00 # 0
3.14159265 18.10.2012 13:48 # +4
И причем тут инициализаторы? Я могу написать и так:
>fluent метод withProp1 кинет исключение.
Гумно прав в основном. В том что в using есть дырка. Инициализаторы здесь ни при чем.
3.14159265 18.10.2012 14:06 # +1
Вот я набросал грубый пример где происходит утечка безо всяких инициализаторов, но с зависимыми ресурсами.
Случай вполне типичный из Connectionа получаем Statement, а из него ResultSet.
http://ideone.com/ZvmIO
Если при освобождении Statementа - упало, соединение не освободили.
phoenixx 18.10.2012 14:21 # +1
3.14159265 18.10.2012 14:22 # +2
>Причина в том что вызов конструктора и dependentResourse
Стоп. Но я же в using все конструкторы написал.
Ни о каких try я не знаю, я ведь специально пишу using, чтоб не писать try.
По-нормальному должно освобождаться.
phoenixx 18.10.2012 14:36 # −1
Там на примере написано во что оно разворачивается. Если бы те кто используют using читали бы это, они бы знали об этом. Просто использовать using незная как он работает в действительности надеясь на "всемогущий фреймворк" как-то глупо.
Почему так, нужно поискать у Липперта. Он рассказывал причину, почему они так сделали.
3.14159265 18.10.2012 14:56 # +2
http://govnokod.ru/11950#comment156393
Конечно кидать исключения из конструкторов и инициализаторов некошерно. Но!
А если у нас там стоит какой-то Wait, который ожидает пока придет Pulse с другого потока - "ресурс освобожден поцоны! "
И тут в наш тред внезапно врывается ThreadInterruptedException.
koodeer 18.10.2012 07:47 # +1
В частности, этот пост создан по мотивам http://sergeyteplyakov.blogspot.com/2012/05/using.html
Так?
TarasB 18.10.2012 09:47 # +5
absolut 18.10.2012 09:55 # +4
3.14159265 18.10.2012 15:03 # +4
3.14159265 23.10.2012 20:33 # +1
Да это не новость, что Гумно ничего своего не придумывает - как и положено гумну он копипастит чужое.
Так ведь с самого начала было. Только год назад он пастами всё закидывал. Другое дело что теперь до него наконец дошло, что сайт называется ГовноКод. И он постит код. Это большой прогресс между прочим.
Ну и похер что этот код где-то уже был, тут ведь не было. А именно тут ему самое место. Поэтому Гумно и получил плюс.