Re[10]: Кошерное использование using
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 29.06.09 11:14
Оценка: 18 (4) +2
Здравствуйте, _FRED_, Вы писали:

_FR> В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.


Совершенно бесполезная вещь. Если уж OOM вылетел, никакая сборка мусора уже не поможет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
AVK Blog
Re[12]: Кошерное использование using
От: Arboz Россия  
Дата: 29.06.09 14:30
Оценка: 29 (4)
MC>Может, но исключения OutOfMemoryException, StackOverflowException и ExecutionEngineException не отлавливаются вообще никак, и в этом случае происходит неизбежное закрытие программы.

Из приведенных только StackOverflowException обладает подобной особенностью по докам.

Вообще же

Исключения SEH всегда доставлялись средой CLR управляемому коду, используя ту же механику, что и для исключений, возникающих в самой программе.


К слову, в версии, 4.0 нас ждет интересная особенность

В версии 4 среды CLR группа разработчиков продукта делает исключения, указывающие на повреждение состояния процесса, отличными от всех прочих исключений. Мы выделили около десяти исключений SEH, которые будут указывать на повреждение состояния процесса. Их обозначения относятся к контексту, в котором создается исключение, а не к самому типу исключения. Это значит, что нарушения прав доступа, полученные от Windows, будут помечены как исключения CSE (исключения поврежденного состояния), а исключения, возникающие в коде пользователя в результате порождения нового System.AccessViolationException, не будут помечены как CSE
...
Начиная с версии 4 система исключений среды CLR не будет доставлять исключения CSE управляемому коду, если код не укажет явно, что он может обрабатывать исключения поврежденного состояния процесса. Это означает, что оператору catch (Exception e) в управляемом коде CSE передаваться не будут.


Оригинал
Re[7]: Кошерное использование using
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.06.09 15:27
Оценка: 4 (1) +2
Здравствуйте, jedi, Вы писали:

J>При чем здесь сбой в оперативной памяти?

J>Банально — пытались записать в ивент лог, что принято новое соединения, произошло исключение — не хватило прав. Все, пусть сокет висит?

Ну а запись в эвент-лог где, в точке №1? Тогда это просто не правильно

J>Я понимаю, что сборщик мусора все это когда-то вычистит. Но для 24/7 приложения это не годится.


Так, стоп. Сборщик мусора как раз для 24/7 приложения существует. Лучше почистить когда-то, чем вообще никогда.

J>Я всего лишь спросил, как принято поступать в таких ситуациях. Вы же принялись убеждать, что все это фигня, думать об этом не нужно и сбрщик мусора когда-то почистит.


Вот именно, думать об этом не нужно. Вы никогда не сможете обработать все возможные сбои, поэтому займитесь актуальными. Сбой инициализации стека метода и сбой оператора присваивания настолько маловероятны, что на них вообще не стоит тратить время.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[17]: Кошерное использование using
От: Arboz Россия  
Дата: 29.06.09 15:30
Оценка: 1 (1) +1
J>За это спасибо.
J>В контексте нашего разговора — как Вы считаете, имеет смысл ли смысл ловить OutOfMemoryException на самом верхнем уровне? В смысле, на уровне соединения в сервере, дабы закрыть его и позволить остальным клиентам обслуживаться нормально? Если да, то есть ли какие-то подводные камни?

Если вы работаете с большими объемами (иными словами, если появление этого исключения хоть сколько-нибудь ожидаемо), то нужно.
Подводных камней тут не вижу.
Re: Кошерное использование using
От: Lloyd Россия  
Дата: 27.06.09 13:05
Оценка: +2
Здравствуйте, jedi, Вы писали:

J>Внимание, вопрос. Как это кошерно обработать?


Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.
Re[3]: Кошерное использование using
От: anton_t Россия  
Дата: 27.06.09 16:25
Оценка: -2
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, Lloyd, Вы писали:


L>>Здравствуйте, jedi, Вы писали:


J>>>Внимание, вопрос. Как это кошерно обработать?


L>>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.


J>Я обеими руками за. Только вот не вижу как это применить в данной ситуации


Как вариант: передавать в конструктор не сокет, а номер порта, а сокет создавать в конструкторе.
Re[6]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 16:39
Оценка: -2
Здравствуйте, anton_t, Вы писали:

J>>
J>>    private void OnAccept(IAsyncResult ar)
J>>    {
J>>        socket = _listener.EndAccept(ar);
J>>        new Connection(socket);
J>>    }
J>>


J>>Где Вы здесь увидели номер порта?


_>Вы сказали, что не знаете, как применить здесь принцип "кто создаёт объект, тот его уничтожает", я привёл вариант. Какие-то проблемы с этим?


Не хамите. Если уж беретесь что-то советовать, то хотя бы посмотрите на код, который я привел в самом первом сообщении и повторил специально для Вас. Где Вы там видите номер порта?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[8]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 17:04
Оценка: -2
Здравствуйте, anton_t, Вы писали:

_>Прежде всего

Где Вы здесь увидели номер порта?

мало походит на вежливое обращение, так что замечаем брёвнышки сначала в своём глазу.


Извините, но если Вы не удосужились прочитать вопрос и понять код в нем приведенный — зачем что-то отвечать?

_>По теме: вы не сказали, насколько вы можете поменять свой код, а я не телепат. Не нужны советы — воля ваша .


Советы ради советов — не нужны.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[7]: Кошерное использование using
От: Ziaw Россия  
Дата: 28.06.09 03:43
Оценка: +2
Здравствуйте, jedi, Вы писали:

J>Банально — пытались записать в ивент лог, что принято новое соединения, произошло исключение — не хватило прав. Все, пусть сокет висит?


Слой логгирования не должен кидать исключений при записи в лог. Никаких. Он вообще должен быть максимально незаметен для кода приложения, а обработка его исключений нарушает это правило.
Re[3]: Кошерное использование using
От: Ziaw Россия  
Дата: 28.06.09 03:55
Оценка: +2
Здравствуйте, TK, Вы писали:


TK>А если удариться в специфику то, создает обычно фабрика, а управляет владелец. И в большинстве случаев, это не брат и сестра, а два разных человека.


В случае с фабрикой "тот кто создает" это не фабрика, а код ее вызывающий. Иначе можно ударяться в специфику до утверждения, что объекты создает new или их конструктор.
Re[8]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 10:41
Оценка: -2
Здравствуйте, _FRED_, Вы писали:

J>>Эмммм... Сокеты — очень ограниченный ресурс. И если их не диспозить совсем, то будет плохо

J>>То же самое — если повиснет открытый файл с блокировкой на чтение/запись — никто с ним не смотжет работать, пока не случится сборка мусора (а случится она может не скоро).
J>>Причем нужна не любая сборка, а первого поколения (ибо у SafeHandle есть финализатор).

_FR>Я не предлагал "их не диспозить". Я сказал, что "диспозить" сокет должен тот, что его создал.


Вы пробовали написать асинхронное приложение. Если да, то должны знать, что у того кто сокет создал (читай — заакцептил) нет ну ни малейшей информации о том, сколько сокету жить.

J>>Почему это плохо, я уже написал выше (и не раз в этом обсужденими). Вы же в очередной раз проводите мне ликбез. Спасибо, я знаком с алгоритмом работы сборщика мусора.


_FR>Тогда что ты называешь "утечкой ресурсов"? Ознакомь тогда пожалуйста со своей терминологией


Это обозначает, что сокет будет недоступен для использования, заблокированный файл нельзя будет читать другим итп. Да, понятно что когда-нибудь сборщик мусора все почистит.
Но когда это случится — сказать нельзя. Тем более учитывая, что объекты с финализатором в нулевом поколении не чистятся. Вот и все.
Мне странно, что такому уважаемому человеку как Вы, это нужно объяснять

J>>Отступлю от темы.

J>>Не в обиду: хорошо написано.
J>>Если честно, из-за этого явления ничего на рсдн спрашивать больше не хочется. Почему-то все априори считают, что спрашивающий — полный ламер, книжек не читал, пороха не нюхал.
J>>И вместо конструктивного обсуждения — продолжают повторять прописные истины.

_FR>http://rsdn.ru/Info/Howtoask.xml ты прочитал? Тебе требовалось конкретно описать проблему. Я не вижу где в своём ответе я обратился к тебе как к "ламеру"?


Вы мне начали читать лекцию о работе сборщика мусора, видимо предполагая, что я о нем впервые слышу.

_FR>Если ты знаешь, что утечки системных ресурсов благодаря сборщику мусора и реализации класса Socket не будет, то объясни как понимать, что "утечка" таки будет?


Я это объяснил уже раз пять по ходу ветки (втом числе еще раз выше в этом сообщении), я не знаю что еще тут добавить...

_FR>Нет, честно, ты http://rsdn.ru/Info/Howtoask.xml прочитал?


Честно, читал. Я как бы на рсдн не первый год. Но что-либо еще писать с предложением пообсуждать не хочется. Проще с умным видом отвечать в ветках новичков и получать свои плюсы.

Вот, смотри:
1) некто adonz
Автор: adontz
Дата: 27.06.09
радостно сказал глупость. При том что финализаторы тут вообще никаким боком. Зачем он это сделал?
2) некто anton_t
Автор: anton_t
Дата: 27.06.09
радостно сказал глупость. Зачем он это сделал?
3) некто Lloyd
Автор: Lloyd
Дата: 27.06.09
радостно сообщил банальность, видимо предполагая что сделал мне откровение. Зачем он это сделал?

И 90% этой ветки — в таком духе. Внимание, вопрос — оно мне надо тратить время читая эти "высокоумные советы"?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[13]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 16:16
Оценка: 9 (1)
Здравствуйте, jedi, Вы писали:

J>Кстати. Я тоже об этом читал у товарища Рихтера.

J>Но вот это:
J>Прекрасно работает. Кому верить?

В данном примере верить вам. Я тоже не раз читал что это исключения нельзя остановить. Может в некоторых ситуациях OutOfMemoryException не может быть поймано, а в некоторых (как в вашем примере) — может. Т.е. возможно это зависит от того при каких условиях CLR выбрасывает это исключение. Хз

Кстаи, можно ссылку на Рихтера об этом исключении? а то в его книге я не нашел где он такое пишет.
Re[34]: Кошерное использование using
От: TK Лес кывт.рф
Дата: 30.06.09 08:49
Оценка: 8 (1)
Здравствуйте, Arboz, Вы писали:

TK>>CriticalFinalizerObject позволяет обработать лишь некоторые из них. Однако, полной гарантии не дает и он.

A>Можете привести пример, в котором не будет вызван Finalize у SafeHandle.

Вариантов полно — от снятия процесса, до power-off
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[12]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 16:00
Оценка: 6 (1)
Здравствуйте, MozgC, Вы писали:

MC>Может, но исключения OutOfMemoryException, StackOverflowException и ExecutionEngineException не отлавливаются вообще никак, и в этом случае происходит неизбежное закрытие программы.


Кстати. Я тоже об этом читал у товарища Рихтера.
Но вот это:


namespace ConsoleApplication1
{
    using System;
    using System.Collections.Generic;

    class Program
    {
        static void Main(string[] args)
        {
            for (; ; )
            {
                try
                {
                    var list = new List<byte[]>();

                    for (; ; )
                        list.Add(new byte[1024 * 1024]);
                }
                catch (OutOfMemoryException)
                {
                    Console.WriteLine("OutOfMemoryException caught");
                }
            }
        }
    }
}


Прекрасно работает. Кому верить?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 09:01
Оценка: 6 (1)
Здравствуйте, jedi, Вы писали:

J>Теперь вопрос. Что будет если случится исключение а) в точке 1; б) в точке 2.


По общепринятым договорённостям, реализация Dispose не должна бросать исключений. То есть внутри реализации Dispose() нужно или вызывать другие Dispose() или гарантировать, что любой код не выбросит исключений. Если теоретически в точке (1) может произойти исключение, то нужно этот код обернуть в try\catch, а после catch вызывать уже _socket.Close(); или что-то ещё.

J>Кто-то должен вызвать Close() сокету (иначе будет висеть у нас занятый порт до сборки мусора).


Теперь второе, более важно замечание. Управлять временем жизни объекта следует тому, что его создал объект. В вашем случае этот принцип нарушен, что может привести к многим неприятностям, например:
J>    private void OnAccept(IAsyncResult ar)
J>    {
J>        using (socket = _listener.EndAccept(ar))
J>        {
J>            using(var c1 = new Connection(socket)) {
                          //…
                        }//using
                        // …
                        using(var c2 =  new Connection(socket)) {
                          // Использование c2, а сокет уже тю-тю
                        }//using
J>        }
J>    }


Если же в своём Dispose объект Connection не будет закрывать сокет, то всё будет хорошо.

Если в вашем случае время жизни сокета 1:1 соответствует времени жизни Connection, и сокет не должен разделяться между разными Connection, то я бы создавал сокет прямо в конструкторе Connection. Если по каким-то причинам это не удобно, то, на худой конец, в Connection надо передавать ещё один флаг — уничтожать сокет или не уничтожать при уничтожении Connection.

J>socket = null;

Это вообще бессмысленный код.

Резюмируя, есть три пути решения (по порядку "удобности" и прочей "хорошести" на мой взгляд)
  1. в Connection::Dispose() не закрывать сокет, отдавая эту прерогативу тому, что создал объект
  2. Создавать сокет в конструкторе Connection и гарантированно закрывать в Connection::Dispose(), обрабатывая возможные исключения
  3. Передавать в Connection дополнительный параметр, который скажет, нужно ли закрывать сокет в Connection::Dispose().
Help will always be given at Hogwarts to those who ask for it.
Re[13]: Кошерное использование using
От: Arboz Россия  
Дата: 29.06.09 14:38
Оценка: 1 (1)
Здравствуйте, Arboz, Вы писали:

Да... ибо не ввести в заблуждение: OutOfMemoryException, StackOverflowException не CSE-исключения
Источник

A set of exceptions indicate your process state is corrupted
а. Access Violations are the most common
b. Does not include Out of Memory, Division by Zero, Stack Overflow, Null Reference

Re[5]: Кошерное использование using
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.06.09 13:35
Оценка: +1
Здравствуйте, anton_t, Вы писали:

_>Thread.Abort(), но это depricated вроде как.


Thread.Abort это какой-то экстремальный случай. В нормальной жизни бывает межпотоковая синхронизация, Thread.Interrupt на худой конец.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[4]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 16:30
Оценка: +1
Здравствуйте, anton_t, Вы писали:

J>>Я обеими руками за. Только вот не вижу как это применить в данной ситуации


_>Как вариант: передавать в конструктор не сокет, а номер порта, а сокет создавать в конструкторе.


    private void OnAccept(IAsyncResult ar)
    {
        socket = _listener.EndAccept(ar);
        new Connection(socket);
    }


Где Вы здесь увидели номер порта?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[5]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 09:50
Оценка: :)
Здравствуйте, jedi, Вы писали:

J>
J>public TcpClient EndAcceptTcpClient(IAsyncResult asyncResult)
J>{
J>        // Details skipped.
J>    Socket socket2 = socket.EndAccept(asyncResult);   
J>    return new TcpClient(socket2);
J>}
J>


J>Что произойдет если выделение памяти под объект TcpClient завершится неудачей (исключением OutOfMemoryException)?

Если случится OutOfMemoryException, то судьба сокета — меньшее, о чем надо будет беспокоиться. Есть основания полагать, что приложение дальше долго не проработает.
Re[9]: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 11:07
Оценка: +1
Здравствуйте, jedi, Вы писали:

J>Вы пробовали написать асинхронное приложение. Если да, то должны знать, что у того кто сокет создал (читай — заакцептил) нет ну ни малейшей информации о том, сколько сокету жить.


Поэтому я и предложил аж три варианта.

J>>>Почему это плохо, я уже написал выше (и не раз в этом обсужденими). Вы же в очередной раз проводите мне ликбез. Спасибо, я знаком с алгоритмом работы сборщика мусора.

_FR>>Тогда что ты называешь "утечкой ресурсов"? Ознакомь тогда пожалуйста со своей терминологией

J>Это обозначает, что сокет будет недоступен для использования, заблокированный файл нельзя будет читать другим итп. Да, понятно что когда-нибудь сборщик мусора все почистит.


По сравнению с возникновением OutOfMemory это цветочки. И всё дело именно в этом. Если вдруг OutOfMemory у вас является нормой, то исправлять в первую очередь следует эту ситуацию, а не разбираться с тем, что делать с сокетом. В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.

J>Но когда это случится — сказать нельзя. Тем более учитывая, что объекты с финализатором в нулевом поколении не чистятся. Вот и все.

J>Мне странно, что такому уважаемому человеку как Вы, это нужно объяснять

Объясняется это просто — я ни разу в жизни не считал возникновение OutOfMomory "нормальной ситуацией". Если это исключение возникает, то либо в программе либо в окружении системы что-то не в порядке. Исправлять это я считаю глупо. Это надо устранять. Между прочим, я не обращаю и не провожу эксперименты с OutOfMomory и жизнью после него. Я следую рекомендации не пытаться обработать это исключение.

_FR>>http://rsdn.ru/Info/Howtoask.xml ты прочитал? Тебе требовалось конкретно описать проблему. Я не вижу где в своём ответе я обратился к тебе как к "ламеру"?

J>Вы мне начали читать лекцию о работе сборщика мусора, видимо предполагая, что я о нем впервые слышу.

Вы первый стали говорить об утечке ресурсов.

_FR>>Если ты знаешь, что утечки системных ресурсов благодаря сборщику мусора и реализации класса Socket не будет, то объясни как понимать, что "утечка" таки будет?

J>Я это объяснил уже раз пять по ходу ветки (втом числе еще раз выше в этом сообщении), я не знаю что еще тут добавить...

J>И 90% этой ветки — в таком духе. Внимание, вопрос — оно мне надо тратить время читая эти "высокоумные советы"?


На свой вопрос вы лучше сам сможете ответить себе, а не я — вам, согласны?

Говорить о том, в чём вы не правы (относительно отношения к вашим сообщениям и вашего отношения к отвечающим) мне не интересно. Лучше задумайтесь о том, почему вам так отвечают, и вы, быть может, поймёте, что из ваших сообщений ни разу не понятно, с чем вы боретесь. Вы в своих сообщениях не следуете простому правилу — точно описать проблему, с которой боретесь.
Вы задаёте очень общие вопросы и справедливо получате не ответы, на которые, быть может, рассчитываете. Попробуйте задать вопрос так, что бы лыло понятно, что именно вы не знаете, чего подозреваете и тому подобное.
Help will always be given at Hogwarts to those who ask for it.
Re[13]: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 11:29
Оценка: -1
Здравствуйте, MozgC, Вы писали:

_FR>>>> В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.

AVK>>>Совершенно бесполезная вещь. Если уж OOM вылетел, никакая сборка мусора уже не поможет.
_FR>>Не поможет от чего?
MC>Не поможет освободить память. Как я понимаю перед тем как выбросить OOM CLR сначала сама попытается вызывать сборку мусора.

Тогда после возникновения OOM никакой работы невозможно даже если очень хочется?
Help will always be given at Hogwarts to those who ask for it.
Re[13]: Кошерное использование using
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 29.06.09 11:51
Оценка: +1
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, MozgC, Вы писали:


MC>>Может, но исключения OutOfMemoryException, StackOverflowException и ExecutionEngineException не отлавливаются вообще никак, и в этом случае происходит неизбежное закрытие программы.


J>Кстати. Я тоже об этом читал у товарища Рихтера.

J>Но вот это:

J>

J>namespace ConsoleApplication1
J>{
J>    using System;
J>    using System.Collections.Generic;

J>    class Program
J>    {
J>        static void Main(string[] args)
J>        {
J>            for (; ; )
J>            {
J>                try
J>                {
J>                    var list = new List<byte[]>();

J>                    for (; ; )
J>                        list.Add(new byte[1024 * 1024]);
J>                }
J>                catch (OutOfMemoryException)
J>                {
J>                    Console.WriteLine("OutOfMemoryException caught");
J>                }
J>            }
J>        }
J>    }
J>}
J>


J>Прекрасно работает. Кому верить?


Вообще-то, OutOfMemoryException, в общем случае обработать не удастся. А приведенный тобой пример, следует переписать, согласно предписаниям того самого Рихтера с учетом MemoryFailPoint (в русскоязычном издании посмотри раздел с названием "Прогнозирование успеха операции, требующем много памяти" главы 20) следующим образом:
using System;
using System.Runtime;
public static class Program {
  public static void Main() {
    try {
      // Logically reserve 1.5 GB of memory
      using (MemoryFailPoint mfp = new MemoryFailPoint(1500)) {
      // Perform memory-hungry algorithm in here
      } // Dispose will logically free the 1.5 GB of memory
    }
    catch (InsufficientMemoryException e) {
    // The memory could not be reserved
    Console.WriteLine(e);
    }
   }
}
Re[20]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 13:14
Оценка: :)
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, jedi, Вы писали:


J>>Это все хорошо если обработка происходит в одном месте. В реальном же приложении, файл открывается и начинается обработка в отдельном потоке. закрыть файл там где его открывали не получится. Ровно то же самое с сокетом в моем изначальном примере.


_FR>У меня как-то получалось, наверное я что-то делал неправильно.


По-моему Вы просто не думали об этой ситуации. И, слава Богу, она не возникала. Я же предпочитаю подумать 1 раз и пользовать паттерном в следующий раз.
Например таким:


class Connection
{
    private Connection(Socket socket)
    {
        // Perform initialization
    }
    
    static public Create(Socket socket)
    {
        try
        {
            return new Connection(socket);            
        }
        catch
        {
            socket.Close();
            throw;
        }    
    }
}


Вот и все решение поднятой в начале проблемы. Я не понимаю из-за чего поднялся такой вой

_FR>А в чём разница-то? Вам так же показали ситуацию, при которой вызов Dispose может быть прерван вызовом Thread.Abort(). Как из неё можно было бы выкрутиться и стоит ли вообще пытаться?


Этой ситуации просто не может быть. За мои 10 лет кодирования, я ни разу не применял ни TerminateThread(), ни Thread.Abort() и надеюсь сохранить достаточную трезвость ума, чтоб не применять их и в будущем . Все мои серверные приложения жили (некоторые живут до сих пор) счастливо. Наверное я что-то делал неправильно (с).
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[26]: Кошерное использование using
От: TK Лес кывт.рф
Дата: 30.06.09 18:47
Оценка: +1
Здравствуйте, Аноним, Вы писали:

TK>>Длительные "управляемые" операции надо соответствующим образом проектировать так, что-бы Thread.Abort для их прерывания не требовался. Если же эти операции "падают" с неба то, выносите их в отдельный процесс — потенциальных проблем будет сильно меньше.


А>вот, оказывается вы невнимательно читали пост, ссылку на который я дал. дам же написано кое-что кроме базы данных — создание отчета. а конкретно Crystal Reports (впрочем неважно). Как предлагаете мне управлять стороенней библиотекой и длительность выполнения операции, в частности создания отчета, которая (операция) может растянутся на минуты?


Выносите "Crystal Reports" в отдельный процесс. Понадобится прервать — всегда можно сделать TerminateProcess и забыть о нем.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 12:14
Оценка:
Всем привет!

Такой вопрос. Есть некий класс, конструктор которого принимает в качестве параметра объект, реализующий интерфейс IDisposable.
Соответветвенно сам этот класс тоже реализует IDisposable.


class Connection : IDisposable
{
    private Socket _socket;
    
    public Connection(Socket socket)
    {
        // 1
        _socket = socket;
        // 2
    }
    
    public void Dispose()
    {
        // dispose stage 1
        _socket.Close();
        // dispose stage 2
    }
}

class Foo
{
    private void OnAccept(IAsyncResult ar)
    {
        socket = _listener.EndAccept(ar);
        new Connection(socket);
    }
}



Теперь вопрос. Что будет если случится исключение а) в точке 1; б) в точке 2.
Кто-то должен вызвать Close() сокету (иначе будет висеть у нас занятый порт до сборки мусора).

Такое:
    private void OnAccept(IAsyncResult ar)
    {
        using (socket = _listener.EndAccept(ar))
        {
            new Connection(socket);
            socket = null;
        }
    }


не прокатывает — warning CS0728: Possibly incorrect assignment to local 'conn' which is the argument to a using or lock statement. The Dispose call or unlocking will happen on the original value of the local.

Внимание, вопрос. Как это кошерно обработать?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re: Кошерное использование using
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.06.09 12:49
Оценка:
Здравствуйте, jedi, Вы писали:

J>Внимание, вопрос. Как это кошерно обработать?


В финалайзере
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 13:00
Оценка:
Здравствуйте, adontz, Вы писали:

A>В финалайзере


Спасибо, очень информативно.
А если финалайзер вызвовется через год? Память может и не ресурс, а порты ТCP — вполне себе (странно, да?).
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[3]: Кошерное использование using
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.06.09 13:19
Оценка:
Здравствуйте, jedi, Вы писали:

J>Спасибо, очень информативно.

J>А если финалайзер вызвовется через год? Память может и не ресурс, а порты ТCP — вполне себе (странно, да?).

Если фрагмент кода в исходном сообщении это реальный код, а не иллюстрация, то думаю, что в точке №1 исключения не будет. С какой стати, какая там может произойти ошибка? Вы можете привести хоть один реальный пример исключения в точке №1?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[4]: Кошерное использование using
От: anton_t Россия  
Дата: 27.06.09 13:23
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, jedi, Вы писали:


J>>Спасибо, очень информативно.

J>>А если финалайзер вызвовется через год? Память может и не ресурс, а порты ТCP — вполне себе (странно, да?).

A>Если фрагмент кода в исходном сообщении это реальный код, а не иллюстрация, то думаю, что в точке №1 исключения не будет. С какой стати, какая там может произойти ошибка? Вы можете привести хоть один реальный пример исключения в точке №1?


Thread.Abort(), но это depricated вроде как.
Re[4]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 13:43
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, jedi, Вы писали:


J>>Спасибо, очень информативно.

J>>А если финалайзер вызвовется через год? Память может и не ресурс, а порты ТCP — вполне себе (странно, да?).

A>Если фрагмент кода в исходном сообщении это реальный код, а не иллюстрация, то думаю, что в точке №1 исключения не будет. С какой стати, какая там может произойти ошибка? Вы можете привести хоть один реальный пример исключения в точке №1?


Да что угодно. Поскольку это сервер к которому пишутся плагины. И ошибка в плагине не должна влиять на возможность других клиентов воспользоваться сервисом.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[2]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 13:46
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, jedi, Вы писали:


J>>Внимание, вопрос. Как это кошерно обработать?


L>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.


Я обеими руками за. Только вот не вижу как это применить в данной ситуации
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[5]: Кошерное использование using
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.06.09 14:28
Оценка:
Здравствуйте, jedi, Вы писали:

J>Да что угодно. Поскольку это сервер к которому пишутся плагины. И ошибка в плагине не должна влиять на возможность других клиентов воспользоваться сервисом.


Что угодно бывают разные. Сбой в оперативной памяти не та ошибочная ситуация, которую стоит обрабатывать.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 14:37
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.


Именно.
Re[3]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 14:39
Оценка:
Здравствуйте, jedi, Вы писали:

L>>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.

J>Я обеими руками за. Только вот не вижу как это применить в данной ситуации

Как-как, не закрывать сокет. Пусть закрывает тот кто передает его в конструктор.
Re[4]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 14:54
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, jedi, Вы писали:


L>>>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.

J>>Я обеими руками за. Только вот не вижу как это применить в данной ситуации

MC>Как-как, не закрывать сокет. Пусть закрывает тот кто передает его в конструктор.


У него недостаточно информации, чтобы решить когда это нужно делать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[6]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:02
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, jedi, Вы писали:


J>>Да что угодно. Поскольку это сервер к которому пишутся плагины. И ошибка в плагине не должна влиять на возможность других клиентов воспользоваться сервисом.


A>Что угодно бывают разные. Сбой в оперативной памяти не та ошибочная ситуация, которую стоит обрабатывать.


При чем здесь сбой в оперативной памяти?
Банально — пытались записать в ивент лог, что принято новое соединения, произошло исключение — не хватило прав. Все, пусть сокет висит?

Я понимаю, что сборщик мусора все это когда-то вычистит. Но для 24/7 приложения это не годится.
И, да, я знаю что можно написать так:


Socket socket = null;

try
{
    socket = _listener.EndAccept(ar);
    new Connection(socket);
}
finally
{
    if (socket != null)
        socket.Close();
}


Я всего лишь спросил, как принято поступать в таких ситуациях. Вы же принялись убеждать, что все это фигня, думать об этом не нужно и сбрщик мусора когда-то почистит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[5]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 15:05
Оценка:
Здравствуйте, jedi, Вы писали:

J>У него недостаточно информации, чтобы решить когда это нужно делать.


Судя по вашему примеры вы вообще заморачиваетесь. Как сказал adontz — не должно быть никакого исключения в указанных вами точках, вы придумываете из разряда "а что если завтра на нас упадет ядерная бомба" — вероятности одинаковые. Хотя у варианта с ядерной бомбой вероятность и то наверное повыше
Re[2]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:05
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, jedi, Вы писали:


J>>Внимание, вопрос. Как это кошерно обработать?


A>В финалайзере


Да, и финалайзер тут на фиг не упал. Ибо у класса Socket уже есть финалайзер, который закроет хендл сокета.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[6]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:06
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Судя по вашему примеры вы вообще заморачиваетесь. Как сказал adontz — не должно быть никакого исключения в указанных вами точках, вы придумываете из разряда "а что если завтра на нас упадет ядерная бомба" — вероятности одинаковые. Хотя у варианта с ядерной бомбой вероятность и то наверное повыше


Спасибо, Ваша помощь была для меня бесценна.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[7]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 15:12
Оценка:
Здравствуйте, jedi, Вы писали:

class Connection : IDisposable
{
    private Socket _socket;
    
    public Connection(Socket socket)
    {
        try
        {
          // 1
          _socket = socket;
          // 2
        }
        catch
        {
          socket.Close();
          throw;
        }
    }
    
    public void Dispose()
    {
        // dispose stage 1
        if(_socket != null)
          _socket.Close();
        // dispose stage 2
    }
}


Так чем-нибудь не устраивает?
Но повторюсь, подумайте как можно сделать дизайн так, чтобы закрытием сокета занимался тот кто его создает.
Re[8]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:16
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Так чем-нибудь не устраивает?


Если вы почитаете ветку выше, я привел один-в-один такой же код.
В целом он меня устраивает. Я всего лишь пытался узнать есть ли какие-то штатные методы/паттерны для этой ситуации (я в .NET недавно).

MC>Но повторюсь, подумайте как можно сделать дизайн так, чтобы закрытием сокета занимался тот кто его создает.


Вы никогда не писали асинхронных серверов? Откуда коду принимающему соединения знать когда его нужно закрыть. Логика кода нелийнейная.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[9]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 15:21
Оценка:
Здравствуйте, jedi, Вы писали:

J>Если вы почитаете ветку выше, я привел один-в-один такой же код.

J>В целом он меня устраивает. Я всего лишь пытался узнать есть ли какие-то штатные методы/паттерны для этой ситуации (я в .NET недавно).

Нет, это не "один-в-один такой же код". В вашем случае такую конструкцию нужно будет писать в каждом месте создания объекта Connection. В моем варианте — нет.
Re[10]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:24
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, jedi, Вы писали:


J>>Если вы почитаете ветку выше, я привел один-в-один такой же код.

J>>В целом он меня устраивает. Я всего лишь пытался узнать есть ли какие-то штатные методы/паттерны для этой ситуации (я в .NET недавно).

MC>Нет, это не "один-в-один такой же код". В вашем случае такую конструкцию нужно будет писать в каждом месте создания объекта Connection. В моем варианте — нет.


Да, извините, бегло смотрел. Ваш код не гарантирует очистки в случае исключения в точке (1). Хотя, я понял, вы считаете это не нужно. А я считаю нужно. Давайте на этом и разойдемся, а то так можно долго спорить
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[11]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 15:25
Оценка:
Здравствуйте, jedi, Вы писали:

J>Да, извините, бегло смотрел. Ваш код не гарантирует очистки в случае исключения в точке (1). Хотя, я понял, вы считаете это не нужно. А я считаю нужно. Давайте на этом и разойдемся, а то так можно долго спорить


Вы опять невнимательно смотрели Мой код гарантирует очистку в случае исключения в точке 1.
Re[11]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:30
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, MozgC, Вы писали:


MC>>Здравствуйте, jedi, Вы писали:


J>>>Если вы почитаете ветку выше, я привел один-в-один такой же код.

J>>>В целом он меня устраивает. Я всего лишь пытался узнать есть ли какие-то штатные методы/паттерны для этой ситуации (я в .NET недавно).

MC>>Нет, это не "один-в-один такой же код". В вашем случае такую конструкцию нужно будет писать в каждом месте создания объекта Connection. В моем варианте — нет.


J>Да, извините, бегло смотрел. Ваш код не гарантирует очистки в случае исключения в точке (1). Хотя, я понял, вы считаете это не нужно. А я считаю нужно. Давайте на этом и разойдемся, а то так можно долго спорить


P.S. Точка (1) может быть и не в конструкторе, а например в конструкторе базового типа.
В общем, подумав соглашусь в такой формулировке:

1) класс Connection должен гарантировать, что исключения не будет до строки _socket = socket.
2) Если исключение будет после, он обязан его поймать и сокет закрыть, исключение перебросить.
3) Если возникает OutOfMemoryException например при попытке выделения памяти под Connection — все равно мы уже ничего сделать не можем и надо потушить свет.

Я прав?
В любом случае, спасибо за помощь
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[8]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:34
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, jedi, Вы писали:


J>>При чем здесь сбой в оперативной памяти?

J>>Банально — пытались записать в ивент лог, что принято новое соединения, произошло исключение — не хватило прав. Все, пусть сокет висит?

A>Ну а запись в эвент-лог где, в точке №1? Тогда это просто не правильно


J>>Я понимаю, что сборщик мусора все это когда-то вычистит. Но для 24/7 приложения это не годится.


A>Так, стоп. Сборщик мусора как раз для 24/7 приложения существует. Лучше почистить когда-то, чем вообще никогда.


J>>Я всего лишь спросил, как принято поступать в таких ситуациях. Вы же принялись убеждать, что все это фигня, думать об этом не нужно и сбрщик мусора когда-то почистит.


A>Вот именно, думать об этом не нужно. Вы никогда не сможете обработать все возможные сбои, поэтому займитесь актуальными. Сбой инициализации стека метода и сбой оператора присваивания настолько маловероятны, что на них вообще не стоит тратить время.


Есть еще MemoryOverflowException ... Но тот же Рихтер пишет что это попа и обрабытывать его бессмысленно.
В общем, Вы наверное правы, спасибо
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[9]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 15:38
Оценка:
Вы бы привели тогда реальный пример. А то вам отвечаешь — а вы начинаете придумывать какие-то ситуации (которых по вашему конкретному примеру не может быть) на ходу.
Re[10]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:41
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Вы бы привели тогда реальный пример. А то вам отвечаешь — а вы начинаете придумывать какие-то ситуации (которых по вашему конкретному примеру не может быть) на ходу.


Что значит не может быть?

По-Вашему эта строка:

new Connection(socket);


не может вызвать OutOfMemoryException? Другой вопрос, что, как справедливо заметил adontz, это обрабатывать не надо.

P.S. Не спорьте больше, я и с Вами и с adontz-ем согласился. Спасибо.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[11]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 15:51
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, MozgC, Вы писали:


MC>>Вы бы привели тогда реальный пример. А то вам отвечаешь — а вы начинаете придумывать какие-то ситуации (которых по вашему конкретному примеру не может быть) на ходу.


J>Что значит не может быть?

Значит что, например, в вашем примере нет базового класса с конструктором.

J>По-Вашему эта строка:


J>
J>new Connection(socket);
J>


J>не может вызвать OutOfMemoryException? Другой вопрос, что, как справедливо заметил adontz, это обрабатывать не надо.


Может, но исключения OutOfMemoryException, StackOverflowException и ExecutionEngineException не отлавливаются вообще никак, и в этом случае происходит неизбежное закрытие программы.

J>P.S. Не спорьте больше, я и с Вами и с adontz-ем согласился. Спасибо.

Не за что
Re[14]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 16:27
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>В данном примере верить вам. Я тоже не раз читал что это исключения нельзя остановить. Может в некоторых ситуациях OutOfMemoryException не может быть поймано, а в некоторых (как в вашем примере) — может. Т.е. возможно это зависит от того при каких условиях CLR выбрасывает это исключение. Хз


Ну тогда мы и в исходном примере можем обработать это исключение, закрыть сокет и позволить подключившимся клиентам нормально работать. Даже если какому то из них не хватит памяти — помрет только это соединение, остальные останутся жить, сервер продолжит работу. Что нам и нужно.

MC>Кстаи, можно ссылку на Рихтера об этом исключении? а то в его книге я не нашел где он такое пишет.


Сейчас быстро посмотрел в книге, тоже не смог найти. Возможно я что-то путаю, и это был не Рихтер. Но что-то в таком духе я оперделенно читал Если вспомню/найду, обязательно отпишусь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[5]: Кошерное использование using
От: anton_t Россия  
Дата: 27.06.09 16:36
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, anton_t, Вы писали:


J>>>Я обеими руками за. Только вот не вижу как это применить в данной ситуации


_>>Как вариант: передавать в конструктор не сокет, а номер порта, а сокет создавать в конструкторе.


J>
J>    private void OnAccept(IAsyncResult ar)
J>    {
J>        socket = _listener.EndAccept(ar);
J>        new Connection(socket);
J>    }
J>


J>Где Вы здесь увидели номер порта?


Вы сказали, что не знаете, как применить здесь принцип "кто создаёт объект, тот его уничтожает", я привёл вариант. Какие-то проблемы с этим?
Re[7]: Кошерное использование using
От: anton_t Россия  
Дата: 27.06.09 16:51
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, anton_t, Вы писали:


J>>>
J>>>    private void OnAccept(IAsyncResult ar)
J>>>    {
J>>>        socket = _listener.EndAccept(ar);
J>>>        new Connection(socket);
J>>>    }
J>>>


J>>>Где Вы здесь увидели номер порта?


_>>Вы сказали, что не знаете, как применить здесь принцип "кто создаёт объект, тот его уничтожает", я привёл вариант. Какие-то проблемы с этим?


J>Не хамите. Если уж беретесь что-то советовать, то хотя бы посмотрите на код, который я привел в самом первом сообщении и повторил специально для Вас. Где Вы там видите номер порта?

Прежде всего

Где Вы здесь увидели номер порта?

мало походит на вежливое обращение, так что замечаем брёвнышки сначала в своём глазу.
По теме: вы не сказали, насколько вы можете поменять свой код, а я не телепат. Не нужны советы — воля ваша .
Re[2]: Кошерное использование using
От: TK Лес кывт.рф
Дата: 27.06.09 22:46
Оценка:
Здравствуйте, Lloyd, Вы писали:

J>>Внимание, вопрос. Как это кошерно обработать?

L>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.

А если удариться в специфику то, создает обычно фабрика, а управляет владелец. И в большинстве случаев, это не брат и сестра, а два разных человека.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[7]: Кошерное использование using
От: TK Лес кывт.рф
Дата: 27.06.09 22:58
Оценка:
Здравствуйте, jedi, Вы писали:

J>Я понимаю, что сборщик мусора все это когда-то вычистит. Но для 24/7 приложения это не годится.

J>Я всего лишь спросил, как принято поступать в таких ситуациях. Вы же принялись убеждать, что все это фигня, думать об этом не нужно и сбрщик мусора когда-то почистит.

Ваше 24/7 приложение это прокат авто или такси? Если такси то, не пускайте клиентов за руль, а если прокат то, в случае аврии — вызывайте страховую...
В приложении это может быть так, что в одном случае клиенту дается не сокет, а некий высокоуровневый "connection" который, абстрагирует используемый ресурс. либо, клиент выносится в отдельный домен/процесс и в случае проблем он банально выгружается вместе со его всеми сокетами...
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[3]: Кошерное использование using
От: ylem  
Дата: 29.06.09 00:08
Оценка:
L>>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.

TK>А если удариться в специфику то, создает обычно фабрика, а управляет владелец. И в большинстве случаев, это не брат и сестра, а два разных человека.


Один хрен, ему дали сокетом попользоваться, а он его прибивает.
Создает не фабрика, а тот, кто эту фабрику пинает. Фабрика, в известном смысле, воли не имеет (Вам же не приходит в голову сказать, что объект создает конструктор).

Передавайте коннекшену саму фабрику или на худой конец, "фабричный делегат", если уж всё именно так, как Вы задумали.
Re[4]: Кошерное использование using
От: TK Лес кывт.рф
Дата: 29.06.09 05:20
Оценка:
Здравствуйте, ylem, Вы писали:

Y>Один хрен, ему дали сокетом попользоваться, а он его прибивает.


А с "гвоздями" такой use-case вас тоже удивляет?

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


Конструктор занимается только инициализацией экземпляра. Никто не запрещает создавать "не инициализированные" экземпляры.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[4]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 08:57
Оценка:
Здравствуйте, ylem, Вы писали:

L>>>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.


TK>>А если удариться в специфику то, создает обычно фабрика, а управляет владелец. И в большинстве случаев, это не брат и сестра, а два разных человека.


Y>Один хрен, ему дали сокетом попользоваться, а он его прибивает.

Y>Создает не фабрика, а тот, кто эту фабрику пинает. Фабрика, в известном смысле, воли не имеет (Вам же не приходит в голову сказать, что объект создает конструктор).

А вот посмотрите на класс StreamWriter in FCL. У него есть такоей конструктор:

public StreamWriter(Stream stream)


и его метод Dispose(Close) закрывает поток, который ему передали в конструкторе.

Closes the current StreamWriter object and the underlying stream.

public override void Close()


Такие примеры в FCL еще есть. Например таков internal конструктор класса TcpClient, прнимающий Socket.

И, кстати, внутри TcpListener мы можем видеть примерно такой код:


public TcpClient EndAcceptTcpClient(IAsyncResult asyncResult)
{
        // Details skipped.
    Socket socket2 = socket.EndAccept(asyncResult);   
    return new TcpClient(socket2);
}


Как видим, здесь писатели из Microsoft плюнули на возможное OutOfMemoryException и утечку сокета (до сборки мусора). И после этой ветки я склоняюсь к мнению, что правильно сделали .

Y>Передавайте коннекшену саму фабрику или на худой конец, "фабричный делегат", если уж всё именно так, как Вы задумали.


Зачем такие сложности? Какие я получу от этого преимущества в моем коде?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[2]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 09:16
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Если в вашем случае время жизни сокета 1:1 соответствует времени жизни Connection, и сокет не должен разделяться между разными Connection, то я бы создавал сокет прямо в конструкторе Connection. Если по каким-то причинам это не удобно, то, на худой конец, в Connection надо передавать ещё один флаг — уничтожать сокет или не уничтожать при уничтожении Connection.


Т.е Вы предлагает в конструктор Connection передавать "IAsyncResult ar" и внутри вызывать "socket = _listener.EndAccept(ar)". Мне почему-то не кажется это хорошим решением.
Хотя бы потому, что классу Connection не нужно знать каким образом было получено соединения — асинхронным BeginAccept, синхронным Accept, или вообще сервер сам присоеденился к клиенту (т.н. passive mode). Кроме того, в более общем случае там будет не Socket, а Stream (например с поддержкой шифрования или без). Так что Ваше решение просто повысит связность кода без всяких бенефитов.

_FR>Резюмируя, есть три пути решения (по порядку "удобности" и прочей "хорошести" на мой взгляд)

_FR>

    _FR>
  1. в Connection::Dispose() не закрывать сокет, отдавая эту прерогативу тому, что создал объект
    _FR>
  2. Создавать сокет в конструкторе Connection и гарантированно закрывать в Connection::Dispose(), обрабатывая возможные исключения
    _FR>
  3. Передавать в Connection дополнительный параметр, который скажет, нужно ли закрывать сокет в Connection::Dispose().
    _FR>

Да, это все хорошо. За исключение возможного OutOfMemoryException при выполнении "new Connection". Но сам Microsoft на такие ситуации забивает, так что ... (Re[4]: Кошерное использование using
Автор: jedi
Дата: 29.06.09
)

В любом случае спасибо. Но мне кажется Вы немножко догматичны в следовании правилу "Управлять временем жизни объекта следует тому, что его создал объект.". Инога это не работает — например в случае с "обертывающими объектами". См. тот же пример StreamWriter <-> Stream. Кстати, об этом случае хорошо и подробно написано у Рихтера (гл.20, "Интересная проблема с зависимостью").
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[3]: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 09:35
Оценка:
Здравствуйте, jedi, Вы писали:

_FR>>Если в вашем случае время жизни сокета 1:1 соответствует времени жизни Connection, и сокет не должен разделяться между разными Connection, то я бы создавал сокет прямо в конструкторе Connection. Если по каким-то причинам это не удобно, то, на худой конец, в Connection надо передавать ещё один флаг — уничтожать сокет или не уничтожать при уничтожении Connection.


J>Т.е Вы предлагает в конструктор Connection передавать "IAsyncResult ar" и внутри вызывать "socket = _listener.EndAccept(ar)".


Что бы узнать, как тебе поступить в твоём частном случае нужно сидеть как можно больше кода. По тому, что было показано в сообщении, на которое я ответил, я не могу ничего предложить по
IAsyncResult.

J>Да, это все хорошо. За исключение возможного OutOfMemoryException при выполнении "new Connection". Но сам Microsoft на такие ситуации забивает, так что ... (Re[4]: Кошерное использование using
Автор: jedi
Дата: 29.06.09
)


Не понятно, откуда там утечка.

J>В любом случае спасибо. Но мне кажется Вы немножко догматичны в следовании правилу "Управлять временем жизни объекта следует тому, что его создал объект.". Инога это не работает — например в случае с "обертывающими объектами". См. тот же пример StreamWriter <-> Stream. Кстати, об этом случае хорошо и подробно написано у Рихтера (гл.20, "Интересная проблема с зависимостью").


Если бы ты мог обратить внимание, сколько непонятностей на формах вызывает такое поведение, то понял бы, что повторять эту архитектуру не стоит.
Help will always be given at Hogwarts to those who ask for it.
Re[4]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 09:45
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Что бы узнать, как тебе поступить в твоём частном случае нужно сидеть как можно больше кода. По тому, что было показано в сообщении, на которое я ответил, я не могу ничего предложить по

_FR>IAsyncResult.

Да я уже давно решил как поступить Сейчас идет "философский" треп. А общий случай был описан в моем исходном сообщении — это передача disposable-объекта в конструктор.
Вы предлагаете радикальное решение — не передавать вообще. Я в свою очередь описал почему все-таки иногда это нужно.

J>>Да, это все хорошо. За исключение возможного OutOfMemoryException при выполнении "new Connection". Но сам Microsoft на такие ситуации забивает, так что ... (Re[4]: Кошерное использование using
Автор: jedi
Дата: 29.06.09
)


_FR>Не понятно, откуда там утечка.


public TcpClient EndAcceptTcpClient(IAsyncResult asyncResult)
{
        // Details skipped.
    Socket socket2 = socket.EndAccept(asyncResult);   
    return new TcpClient(socket2);
}


Что произойдет если выделение памяти под объект TcpClient завершится неудачей (исключением OutOfMemoryException)?

_FR>Если бы ты мог обратить внимание, сколько непонятностей на формах вызывает такое поведение, то понял бы, что повторять эту архитектуру не стоит.


Кто ж спорит, но иногда-все таки это нужно — если приложение асинхронное. Мы все-таки в реальном мире живем, и следовать умным правилам не всегда получается
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[6]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 09:52
Оценка:
Здравствуйте, samius, Вы писали:

J>>Что произойдет если выделение памяти под объект TcpClient завершится неудачей (исключением OutOfMemoryException)?

S>Если случится OutOfMemoryException, то судьба сокета — меньшее, о чем надо будет беспокоиться. Есть основания полагать, что приложение дальше долго не проработает.

Если это WinForms приложение — то бог с ним пусть умирает. Если же это корректно написанное серверное приложение, то худшее что должно случиться — нескольким клиентам будет отказано в доступе, остальные продолжат рабту как ни в чем не бывало. Да, администратору будет послано письмо с извещением о том, что случилось и он примет меры — например уменьшит максимум одновременных подключений. Но сервер должен продолжить работу.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[5]: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 10:01
Оценка:
Здравствуйте, jedi, Вы писали:

J>Вы предлагаете радикальное решение — не передавать вообще. Я в свою очередь описал почему все-таки иногда это нужно.


Я предложил не "не передовать", а не уничтожать переданный в конструктор объект.

J>>>Да, это все хорошо. За исключение возможного OutOfMemoryException при выполнении "new Connection". Но сам Microsoft на такие ситуации забивает, так что ... (Re[4]: Кошерное использование using
Автор: jedi
Дата: 29.06.09
)

_FR>>Не понятно, откуда там утечка.
J>Что произойдет если выделение памяти под объект TcpClient завершится неудачей (исключением OutOfMemoryException)?

Одно из двух:
  1. Приложение завершится, при этом ось закроет сокет
  2. Приложение не завершится, где-то выше по стеку исключение будет поймано и как-то обработано. Тогда при следующей же сборке мусора будет найден объект типа Socket, на который нет ни одной ссылки из корней. Этот объект будет собран GC, у объекта будет вызван файнализатор. У поля объекта m_Handle так же будет вызван завершитель. Никакие ресурсы никуда не утекут.

_FR>>Если бы ты мог обратить внимание, сколько непонятностей на формах вызывает такое поведение, то понял бы, что повторять эту архитектуру не стоит.

J>Кто ж спорит, но иногда-все таки это нужно — если приложение асинхронное. Мы все-таки в реальном мире живем, и следовать умным правилам не всегда получается

Не всегда получает придумать, как сделать правильно
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 10:05
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, samius, Вы писали:


J>>>Что произойдет если выделение памяти под объект TcpClient завершится неудачей (исключением OutOfMemoryException)?

S>>Если случится OutOfMemoryException, то судьба сокета — меньшее, о чем надо будет беспокоиться. Есть основания полагать, что приложение дальше долго не проработает.

J>Если это WinForms приложение — то бог с ним пусть умирает. Если же это корректно написанное серверное приложение, то худшее что должно случиться — нескольким клиентам будет отказано в доступе, остальные продолжат рабту как ни в чем не бывало.

Я бы сказал, что нескольким будет отказано в доступе, а многим не удастся завершить сессию соединения. Если OOME случился в одном конструкторе, то слишком много шансов на то, что он случится в любом другом конструкторе.

J>Да, администратору будет послано письмо с извещением о том, что случилось и он примет меры — например уменьшит максимум одновременных подключений. Но сервер должен продолжить работу.

Вряд ли это будет полноценная работа.
Re[8]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 10:19
Оценка:
Здравствуйте, samius, Вы писали:

J>>Да, администратору будет послано письмо с извещением о том, что случилось и он примет меры — например уменьшит максимум одновременных подключений. Но сервер должен продолжить работу.

S>Вряд ли это будет полноценная работа.

Я извинюясь, в чемм будет ее неполноценность? Какое-то количество клиентов отвалилось — освободилась память. Она хорошая, никто по ней не ездил, Access Vialotaion не случился, Stack Overflow не было
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[6]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 10:19
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Я предложил не "не передовать", а не уничтожать переданный в конструктор объект.


Эмммм... Сокеты — очень ограниченный ресурс. И если их не диспозить совсем, то будет плохо
То же самое — если повиснет открытый файл с блокировкой на чтение/запись — никто с ним не смотжет работать, пока не случится сборка мусора (а случится она может не скоро).
Причем нужна не любая сборка, а первого поколения (ибо у SafeHandle есть финализатор).

J>>>>Да, это все хорошо. За исключение возможного OutOfMemoryException при выполнении "new Connection". Но сам Microsoft на такие ситуации забивает, так что ... (Re[4]: Кошерное использование using
Автор: jedi
Дата: 29.06.09
)

_FR>>>Не понятно, откуда там утечка.
J>>Что произойдет если выделение памяти под объект TcpClient завершится неудачей (исключением OutOfMemoryException)?

_FR>Одно из двух:

_FR>

    _FR>
  1. Приложение завершится, при этом ось закроет сокет
    _FR>
  2. Приложение не завершится, где-то выше по стеку исключение будет поймано и как-то обработано. Тогда при следующей же сборке мусора будет найден объект типа Socket, на который нет ни одной ссылки из корней. Этот объект будет собран GC, у объекта будет вызван файнализатор. У поля объекта m_Handle так же будет вызван завершитель. Никакие ресурсы никуда не утекут.
    _FR>

Почему это плохо, я уже написал выше (и не раз в этом обсужденими). Вы же в очередной раз проводите мне ликбез. Спасибо, я знаком с алгоритмом работы сборщика мусора.

Отступлю от темы.

Не в обиду: хорошо написано.
Если честно, из-за этого явления ничего на рсдн спрашивать больше не хочется. Почему-то все априори считают, что спрашивающий — полный ламер, книжек не читал, пороха не нюхал.
И вместо конструктивного обсуждения — продолжают повторять прописные истины.

Идельный пример — в этой ветке Синхронизация
Автор: jedi
Дата: 17.06.09
. Некто Воронков Василий, с умным видом доказывал мне что доступ к булевой переменной синхронизировать не нужно. При этом не удосужившись ни прочитать код, ни понять что там написано. Но во всех его постах была уверенность, что я о синхронизации впервые слышу и меня нужно непременно просветить. Когда же ему указли на то, что он мягко говоря не прав, человек предпочел замолчать, даже не извинившись передом мной за то, что с умным видом занимался менторством, при этом неся полную чушь.

В общем печально все это.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[9]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 10:26
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, samius, Вы писали:


S>>Вряд ли это будет полноценная работа.


J>Я извинюясь, в чемм будет ее неполноценность? Какое-то количество клиентов отвалилось — освободилась память. Она хорошая, никто по ней не ездил, Access Vialotaion не случился, Stack Overflow не было


Хорошо, несколько клиентов отвалятся, память освободится, вновь подключившемуся клиенту памяти под экземпляр класса Connection хватит. Если никаких других выделений памяти для обработки соединения с клиентом не потребуется, то все будет впорядке. А если нужно десериализовать из сокета какие-то данные, сходить в БД, прочитать граф объектов и т.п., то шансы на успех выполнения итих действий малы.
Re[7]: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 10:27
Оценка:
Здравствуйте, jedi, Вы писали:

_FR>>Я предложил не "не передовать", а не уничтожать переданный в конструктор объект.


J>Эмммм... Сокеты — очень ограниченный ресурс. И если их не диспозить совсем, то будет плохо

J>То же самое — если повиснет открытый файл с блокировкой на чтение/запись — никто с ним не смотжет работать, пока не случится сборка мусора (а случится она может не скоро).
J>Причем нужна не любая сборка, а первого поколения (ибо у SafeHandle есть финализатор).

Я не предлагал "их не диспозить". Я сказал, что "диспозить" сокет должен тот, что его создал.

J>Почему это плохо, я уже написал выше (и не раз в этом обсужденими). Вы же в очередной раз проводите мне ликбез. Спасибо, я знаком с алгоритмом работы сборщика мусора.


Тогда что ты называешь "утечкой ресурсов"? Ознакомь тогда пожалуйста со своей терминологией

J>Отступлю от темы.

J>Не в обиду: хорошо написано.
J>Если честно, из-за этого явления ничего на рсдн спрашивать больше не хочется. Почему-то все априори считают, что спрашивающий — полный ламер, книжек не читал, пороха не нюхал.
J>И вместо конструктивного обсуждения — продолжают повторять прописные истины.

http://rsdn.ru/Info/Howtoask.xml ты прочитал? Тебе требовалось конкретно описать проблему. Я не вижу где в своём ответе я обратился к тебе как к "ламеру"? Если ты знаешь, что утечки системных ресурсов благодаря сборщику мусора и реализации класса Socket не будет, то объясни как понимать, что "утечка" таки будет? Экстрасенсы у нас сидят все в непрофильных форумах — это там принято "догадываться".

J>Идельный пример — в этой ветке Синхронизация
Автор: jedi
Дата: 17.06.09
. Некто Воронков Василий, с умным видом доказывал мне что доступ к булевой переменной синхронизировать не нужно. При этом не удосужившись ни прочитать код, ни понять что там написано. Но во всех его постах была уверенность, что я о синхронизации впервые слышу и меня нужно непременно просветить. Когда же ему указли на то, что он мягко говоря не прав, человек предпочел замолчать, даже не извинившись передом мной за то, что с умным видом занимался менторством, при этом неся полную чушь.


Нет, честно, ты http://rsdn.ru/Info/Howtoask.xml прочитал?
Help will always be given at Hogwarts to those who ask for it.
Re[10]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 10:28
Оценка:
Здравствуйте, samius, Вы писали:

S>Хорошо, несколько клиентов отвалятся, память освободится, вновь подключившемуся клиенту памяти под экземпляр класса Connection хватит. Если никаких других выделений памяти для обработки соединения с клиентом не потребуется, то все будет впорядке. А если нужно десериализовать из сокета какие-то данные, сходить в БД, прочитать граф объектов и т.п., то шансы на успех выполнения итих действий малы.


Т.е. ваше решение — забить, пусть сервер упадет с необрабтанным исключением, данные всех пользователей потеряются, и пусть все клиенты ждут пока администратор проснется и решит проблему?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[11]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 10:39
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, samius, Вы писали:


S>>Хорошо, несколько клиентов отвалятся, память освободится, вновь подключившемуся клиенту памяти под экземпляр класса Connection хватит. Если никаких других выделений памяти для обработки соединения с клиентом не потребуется, то все будет впорядке. А если нужно десериализовать из сокета какие-то данные, сходить в БД, прочитать граф объектов и т.п., то шансы на успех выполнения итих действий малы.


J>Т.е. ваше решение — забить, пусть сервер упадет с необрабтанным исключением, данные всех пользователей потеряются, и пусть все клиенты ждут пока администратор проснется и решит проблему?


Я лишь написал о том, что закрытие единственного сокета после OOME — не суть важная вещь на фоне остальных проблем. В общем случае я не утверждаю, что мне виднее, чем Вам как должен вести себя сервер в такой ситуации. Но толку от того, что Вы не забудете освободить конкретный сокет, будет мало.

Если интересно мнение форумчан на то, что следует предпринимать при OOME, заводите соответствующую тему.
Re[12]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 10:43
Оценка:
Здравствуйте, samius, Вы писали:

S>Я лишь написал о том, что закрытие единственного сокета после OOME — не суть важная вещь на фоне остальных проблем. В общем случае я не утверждаю, что мне виднее, чем Вам как должен вести себя сервер в такой ситуации. Но толку от того, что Вы не забудете освободить конкретный сокет, будет мало.


Ну сокет — это всего лишь пример. Это может быть файл открытый на запись с блокировкой. Или начатая транзакция, которая будет висеть хз сколько итп.

S>Если интересно мнение форумчан на то, что следует предпринимать при OOME, заводите соответствующую тему.


Согласен. Я не совсем корректно поставил вопрос изначально.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[11]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 11:18
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, _FRED_, Вы писали:


_FR>> В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.


AVK>Совершенно бесполезная вещь. Если уж OOM вылетел, никакая сборка мусора уже не поможет.


Просто сборка не поможет. Но если что-то предпринять, отпустить кое-какие ссылки, почистить какие-нибудь кэши, то может и помочь.
Re[10]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 11:20
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Поэтому я и предложил аж три варианта.


Они все мимо кассы при OutOfMemoryException...

J>>>>Почему это плохо, я уже написал выше (и не раз в этом обсужденими). Вы же в очередной раз проводите мне ликбез. Спасибо, я знаком с алгоритмом работы сборщика мусора.

_FR>>>Тогда что ты называешь "утечкой ресурсов"? Ознакомь тогда пожалуйста со своей терминологией

J>>Это обозначает, что сокет будет недоступен для использования, заблокированный файл нельзя будет читать другим итп. Да, понятно что когда-нибудь сборщик мусора все почистит.


_FR>По сравнению с возникновением OutOfMemory это цветочки. И всё дело именно в этом. Если вдруг OutOfMemory у вас является нормой, то исправлять в первую очередь следует эту ситуацию, а не разбираться с тем, что делать с сокетом. В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.


Почему это может возникнуть и почему его нужно обрабатывать — я написал не раз. Например здесь
Автор: jedi
Дата: 29.06.09
. Я же не могу в каждой подветке повторять одни и те же аргументы?

_FR>Объясняется это просто — я ни разу в жизни не считал возникновение OutOfMomory "нормальной ситуацией". Если это исключение возникает, то либо в программе либо в окружении системы что-то не в порядке. Исправлять это я считаю глупо. Это надо устранять. Между прочим, я не обращаю и не провожу эксперименты с OutOfMomory и жизнью после него. Я следую рекомендации не пытаться обработать это исключение.


Я в общем-то давно с этим согласился. Например здесь
Автор: jedi
Дата: 27.06.09
Но для 42/7 приложения единственный способ 100% гарантировать себя от OutOfMemory — это ограничить количество подключений. Но для этого нужно знать максимально количество памяти, которое может понадобится каждому клиенту. Что, как Вы понимаете, в общем случае сделать непросто. И если уж все пошло плохо и памяти таки не хватило — это не повод тушить свет и перезапускать сервер. Вполне можно отказате паре клиентов и жить дальше.

_FR>>>http://rsdn.ru/Info/Howtoask.xml ты прочитал? Тебе требовалось конкретно описать проблему. Я не вижу где в своём ответе я обратился к тебе как к "ламеру"?

J>>Вы мне начали читать лекцию о работе сборщика мусора, видимо предполагая, что я о нем впервые слышу.

_FR>Вы первый стали говорить об утечке ресурсов.


Таки утечка есть ... Ибо объекты, требующие завершения надо завершать вовремя. Иначе — это утечка, несмотря на то что сборщик подберет когда-то.
А если это не утечка, то утечек вообще нет, ибо ось все почистит после закрытия процесса

_FR>>>Если ты знаешь, что утечки системных ресурсов благодаря сборщику мусора и реализации класса Socket не будет, то объясни как понимать, что "утечка" таки будет?

J>>Я это объяснил уже раз пять по ходу ветки (втом числе еще раз выше в этом сообщении), я не знаю что еще тут добавить...

J>>И 90% этой ветки — в таком духе. Внимание, вопрос — оно мне надо тратить время читая эти "высокоумные советы"?


_FR>На свой вопрос вы лучше сам сможете ответить себе, а не я — вам, согласны?


Да я уже собственно ответил. Синдром бакалавра.

_FR>Говорить о том, в чём вы не правы (относительно отношения к вашим сообщениям и вашего отношения к отвечающим) мне не интересно. Лучше задумайтесь о том, почему вам так отвечают, и вы, быть может, поймёте, что из ваших сообщений ни разу не понятно, с чем вы боретесь. Вы в своих сообщениях не следуете простому правилу — точно описать проблему, с которой боретесь.

_FR>Вы задаёте очень общие вопросы и справедливо получате не ответы, на которые, быть может, рассчитываете. Попробуйте задать вопрос так, что бы лыло понятно, что именно вы не знаете, чего подозреваете и тому подобное.

С этим я согласен, вопрос был сформулирован коряво. Но это не опрадывает отвечавших, писавыших явную глупость абы написать что-то. Или я не прав?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[11]: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 11:23
Оценка:
Здравствуйте, AndrewVK, Вы писали:

_FR>> В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.


AVK>Совершенно бесполезная вещь. Если уж OOM вылетел, никакая сборка мусора уже не поможет.


Не поможет от чего?
Help will always be given at Hogwarts to those who ask for it.
Re[12]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 29.06.09 11:26
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, AndrewVK, Вы писали:


_FR>>> В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.


AVK>>Совершенно бесполезная вещь. Если уж OOM вылетел, никакая сборка мусора уже не поможет.


_FR>Не поможет от чего?

Не поможет освободить память. Как я понимаю перед тем как выбросить OOM CLR сначала сама попытается вызывать сборку мусора.
Re[14]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 29.06.09 11:32
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Тогда после возникновения OOM никакой работы невозможно даже если очень хочется?


OOMException может быть выброшено в разных ситуациях. В некоторых случаях продолжение работы возможно. jedi как раз привел тестовый пример в этой ветке
Re[14]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 11:33
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, MozgC, Вы писали:


_FR>>>>> В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.

AVK>>>>Совершенно бесполезная вещь. Если уж OOM вылетел, никакая сборка мусора уже не поможет.
_FR>>>Не поможет от чего?
MC>>Не поможет освободить память. Как я понимаю перед тем как выбросить OOM CLR сначала сама попытается вызывать сборку мусора.

_FR>Тогда после возникновения OOM никакой работы невозможно даже если очень хочется?


Самы тупой пример — пытаемя загрузить в память гигантскую картинку. Хватило памяти — хорошо, обрбатываем ее. Не хватило — перехватили OOM, сказали клиенту "извините" и живем спокойно дальше. Но даже если это произошло мы не должны бросать открытый файл открытым. Вот собственно весь пойнт моих рассуждений в этой ветке
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[15]: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 11:46
Оценка:
Здравствуйте, jedi, Вы писали:

_FR>>>>>> В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.

AVK>>>>>Совершенно бесполезная вещь. Если уж OOM вылетел, никакая сборка мусора уже не поможет.
_FR>>>>Не поможет от чего?
MC>>>Не поможет освободить память. Как я понимаю перед тем как выбросить OOM CLR сначала сама попытается вызывать сборку мусора.
_FR>>Тогда после возникновения OOM никакой работы невозможно даже если очень хочется?

J>Самы тупой пример — пытаемя загрузить в память гигантскую картинку. Хватило памяти — хорошо, обрбатываем ее. Не хватило — перехватили OOM, сказали клиенту "извините" и живем спокойно дальше.


Так память-то освобождается всё-таки, после неудачной попытки загрузить в ней картинку?

J>Но даже если это произошло мы не должны бросать открытый файл открытым. Вот собственно весь пойнт моих рассуждений в этой ветке


И при чём здесь обработка OutOfMemoryException? То есть, файл можно закрыть и не обрабатывая специальным OutOfMemoryException, потому что очистка памяти — не наша забота, а того, кто выбросил OutOfMemoryException.
Help will always be given at Hogwarts to those who ask for it.
Re[16]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 11:55
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, jedi, Вы писали:


_FR>>>>>>> В крайнем случае, вы можете поставить catch на OutOfMemory и вызвать в нём сборку мусора.

AVK>>>>>>Совершенно бесполезная вещь. Если уж OOM вылетел, никакая сборка мусора уже не поможет.
_FR>>>>>Не поможет от чего?
MC>>>>Не поможет освободить память. Как я понимаю перед тем как выбросить OOM CLR сначала сама попытается вызывать сборку мусора.
_FR>>>Тогда после возникновения OOM никакой работы невозможно даже если очень хочется?

J>>Самы тупой пример — пытаемя загрузить в память гигантскую картинку. Хватило памяти — хорошо, обрбатываем ее. Не хватило — перехватили OOM, сказали клиенту "извините" и живем спокойно дальше.


_FR>Так память-то освобождается всё-таки, после неудачной попытки загрузить в ней картинку?


Она не освобождается, она не была даже выделена.

J>>Но даже если это произошло мы не должны бросать открытый файл открытым. Вот собственно весь пойнт моих рассуждений в этой ветке


_FR>И при чём здесь обработка OutOfMemoryException? То есть, файл можно закрыть и не обрабатывая специальным OutOfMemoryException, потому что очистка памяти — не наша забота, а того, кто выбросил OutOfMemoryException.


OutOfMemoryException выбросил оператор new. Он не умеет магически вызывать Dispose() нужным объектам. Ему надо помочь.

Еще раз. Посмотри пример с TcpLinstener.EndAccept и StreamWriter-ом, которые я приводил выше по ветке. Там есть проблема, на которую парни из Microsoft забили. Осознанно или нет — я не знаю.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[14]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 12:02
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Вообще-то, OutOfMemoryException, в общем случае обработать не удастся.


Поподробнее — почему?

ST>А приведенный тобой пример, следует переписать, согласно предписаниям того самого Рихтера с учетом MemoryFailPoint (в русскоязычном издании посмотри раздел с названием "Прогнозирование успеха операции, требующем много памяти" главы 20) следующим образом:


Это интересная техника, но она не имеет отношения к обсуждаемому вопросу. Циатата:

Внимание! Если конструктор MemoryFailPoint не генерирует исключе-
ние, запрошенная память была логически зарезервирована и можно
выполнять алгоритм, требующий много памяти. Однако учтите, что
физически память не была выделена. Это значит, что лишь немного
повысилась вероятность успешного выполнения алгоритма и получения
необходимой памяти. Класс MemoryFailPoint не может гарантировать, что
алгоритм получит необходимую память, даже если конструктор не
сгенерировал исключение. Этот класс призван лишь помочь разработчику
сделать приложение более надежным.

... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[9]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 12:03
Оценка:
Уважаемый SergeyT, с чем конкретно Вы не согласны?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[10]: Кошерное использование using
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 29.06.09 12:13
Оценка:
Здравствуйте, jedi, Вы писали:

J>Уважаемый SergeyT, с чем конкретно Вы не согласны?


Я только о том, что OutOfMemoryException обработать никак не удастся. Например, что делать если при упаковке значимого типа вылетит это исключение? Мест, где неявно выделяется память великое множество и все их обрамить try catch(OOME) будет весьма сложно.
Выбрасывание OOM говорит либо о неверных настройках серверного приложения (т.е. выбрано неверное количество максимально-допустимых подключений или еще чего-то такого), либо об ошибках (багах), которые не обойти простым отловом исключений OOM.
Я не согласен с примером исключения, которое вы пытаетесь обработать. Некоторые типы исключений очень сложно обработать. Попробуйте обработать StackOverflowException. Что у вас получится?

Я уже лет 6 занимаюсь разработкой серверных приложений 24/7 и ни разу не пришлось обрабатывать OOM.
При этом совсем недавно наткнулся на OOM в клиенском приложении. Утечка закралась в один из компонентов, который мы использовали. Так вот, это приложение на разных сборках винды вело себя по разному. На некоторых машинах приложение тупо закрывалось, даже в логе винды не было никаких собощений, не говоря уже о вызове нормальных обработчиков исключений. Кроме того, только лишь на некоторых машинах вызывался и обрабатывался DomainAnhandleException.
Чем бы мне в этом случае помогли catch(OOM)?
Re[11]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 12:30
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Я только о том, что OutOfMemoryException обработать никак не удастся. Например, что делать если при упаковке значимого типа вылетит это исключение? Мест, где неявно выделяется память великое множество и все их обрамить try catch(OOME) будет весьма сложно.


Ну и что? В конечном счете оно будет поймано на верхнем уровне и соединение закроется. Главное, что при этом не останутся висеть не закрытые сокеты, файлы итп.

ST>Выбрасывание OOM говорит либо о неверных настройках серверного приложения (т.е. выбрано неверное количество максимально-допустимых подключений или еще чего-то такого), либо об ошибках (багах), которые не обойти простым отловом исключений OOM.


Я уже писал здесь, что OOM ни в коем случае не является штатной ситуацией. Администратору будет немедленно послано письмо и он примет меры.
А по поводу максимального числа соединений — ну как знать его заранее? Или пессимизировать и ограничивать заведомо маленьким числом?

ST>Я не согласен с примером исключения, которое вы пытаетесь обработать. Некоторые типы исключений очень сложно обработать. Попробуйте обработать StackOverflowException. Что у вас получится?


StackOverflowException я и не предлагал обрабатывать ... Но как бы и добиться его сложно, если вы конечно не используете рекурсивные алгоритмы. Я — не использую никогда.

ST>Я уже лет 6 занимаюсь разработкой серверных приложений 24/7 и ни разу не пришлось обрабатывать OOM.


Я тоже в этом не новичок. Правда раньше писал в основном на с++. Но и под .NET есть сервер, который крутится уже три года без всяких проблем. Сейчас встал вопрос о расширении количества клиентов, и сервер переписывается чтобы соответсвовать новым нуждам. Вот и появился такой вопрос. Мне он не кажется праздным и таким уж очевидным.

ST>При этом совсем недавно наткнулся на OOM в клиенском приложении. Утечка закралась в один из компонентов, который мы использовали. Так вот, это приложение на разных сборках винды вело себя по разному. На некоторых машинах приложение тупо закрывалось, даже в логе винды не было никаких собощений, не говоря уже о вызове нормальных обработчиков исключений. Кроме того, только лишь на некоторых машинах вызывался и обрабатывался DomainAnhandleException.

ST>Чем бы мне в этом случае помогли catch(OOM)?

Я не знаю ситуации, тут сложно сказать. Возможно компонент был неуправляемым и на нехватку памяти накладывались еще какие чудеса. Кто знает?


А в целом — спасибо, интересно услышать мнение человека, который в теме
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[12]: Кошерное использование using
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 29.06.09 12:44
Оценка:
Здравствуйте, jedi, Вы писали:

J>А в целом — спасибо, интересно услышать мнение человека, который в теме


И последнее. Не могу сказать, что мое серверное приложение уж через чур здоровое и мощное, но к нему коннектятся два десятка клиентов через WCF, сервер обрабатывает 5 десятков сообщений в секунду от различного оборудования, рассылает новые состояния объектов клиентам. Все это благополучно кушает до 50 мегабайт памяти и работает на P4 2.4 с 512 метрами памяти.
Но при этом клиентские приложения "кушают" под 200мб памяти и куда прожорливее на процессорное время.
Я это все к тому, что по моему опыту, чтобы серверное приложение съело всю доступную память — нужно здорово постараться.

З.Ы. От темы отвлеклись, но и так понятно, что с ней завязывать уже нужно
Re[17]: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 12:47
Оценка:
Здравствуйте, jedi, Вы писали:

_FR>>Так память-то освобождается всё-таки, после неудачной попытки загрузить в ней картинку?

J>Она не освобождается, она не была даже выделена.

Ну вот видишь, ты сам меня принимаешься учить ;о) а я-то всего имел в виду, что память не остается чем-то занятой :о))

J>>>Но даже если это произошло мы не должны бросать открытый файл открытым. Вот собственно весь пойнт моих рассуждений в этой ветке

_FR>>И при чём здесь обработка OutOfMemoryException? То есть, файл можно закрыть и не обрабатывая специальным OutOfMemoryException, потому что очистка памяти — не наша забота, а того, кто выбросил OutOfMemoryException.
J>OutOfMemoryException выбросил оператор new.

Я говорил о другом: можно написать код, который ставит файл в порядке и без обработки OOM:
using(var file = OpenLargeFile()) {
  // …
}//using

то есть можно обойтись без catch(OutOfMemory) и жить припеваючи.

А ловить OOM на любом new — это паранойя. Если есть метод, который, по спецификации такое может выбросить — ну что ж делать, но ожидать подлянки откуда угодно — глупо, повторю. Пример простой — так же как и OOM, может произойти и ThreadAbortException, и это даже имеет реальные проблемы, так как так же возможны утечки ресурсов. Однако, было бы странно писать код с оглядкой на такое. Так же и здесь. Если ты знаешь, что при некоторых условиях сожет вылететь исключение, то ситуация одна.

При каких условиях может вылететь исключение в коде
new TcpClient(socket2);

И как ты видишь работу приложения после возникновения OutOfMemory в данном случае? Я вижу только один вариант — перезапуститься. При этом утечек не произойдёт.
Help will always be given at Hogwarts to those who ask for it.
Re[13]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 12:47
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>И последнее. Не могу сказать, что мое серверное приложение уж через чур здоровое и мощное, но к нему коннектятся два десятка клиентов через WCF, сервер обрабатывает 5 десятков сообщений в секунду от различного оборудования, рассылает новые состояния объектов клиентам. Все это благополучно кушает до 50 мегабайт памяти и работает на P4 2.4 с 512 метрами памяти.

ST>Но при этом клиентские приложения "кушают" под 200мб памяти и куда прожорливее на процессорное время.Я это все к тому, что по моему опыту, чтобы серверное приложение съело всю доступную память — нужно здорово постараться.

У меня как раз клиентов тысячи, все они коннектятся неругялрно, бывают наплывы, бывет полный простой. Поэтому, если все приконнектятся сразу и сожрут весь сервер, вполне можно отказать парочке — они попробуют позже.

ST>З.Ы. От темы отвлеклись, но и так понятно, что с ней завязывать уже нужно


Согласен. Ее не стоилдо и начинать
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[18]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 12:54
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, jedi, Вы писали:


_FR>>>Так память-то освобождается всё-таки, после неудачной попытки загрузить в ней картинку?

J>>Она не освобождается, она не была даже выделена.

_FR>Ну вот видишь, ты сам меня принимаешься учить ;о) а я-то всего имел в виду, что память не остается чем-то занятой :о))


Вы спросили: "Так память-то освобождается всё-таки, после неудачной попытки загрузить в ней картинку?". Я ответил Если что, извините.

J>>>>Но даже если это произошло мы не должны бросать открытый файл открытым. Вот собственно весь пойнт моих рассуждений в этой ветке

_FR>>>И при чём здесь обработка OutOfMemoryException? То есть, файл можно закрыть и не обрабатывая специальным OutOfMemoryException, потому что очистка памяти — не наша забота, а того, кто выбросил OutOfMemoryException.
J>>OutOfMemoryException выбросил оператор new.

_FR>Я говорил о другом: можно написать код, который ставит файл в порядке и без обработки OOM:

_FR>
_FR>using(var file = OpenLargeFile()) {
_FR>  // …
_FR>}//using
_FR>

_FR>то есть можно обойтись без catch(OutOfMemory) и жить припеваючи.

Это все хорошо если обработка происходит в одном месте. В реальном же приложении, файл открывается и начинается обработка в отдельном потоке. закрыть файл там где его открывали не получится. Ровно то же самое с сокетом в моем изначальном примере.

_FR>А ловить OOM на любом new — это паранойя. Если есть метод, который, по спецификации такое может выбросить — ну что ж делать, но ожидать подлянки откуда угодно — глупо, повторю.


Я и не предлагал его ловить при каждом new, а всего лишь там где в new передается объект, требующий вызов Dispose.

_FR> Пример простой — так же как и OOM, может произойти и ThreadAbortException, и это даже имеет реальные проблемы, так как так же возможны утечки ресурсов. Однако, было бы странно писать код с оглядкой на такое. Так же и здесь. Если ты знаешь, что при некоторых условиях сожет вылететь исключение, то ситуация одна.


Это та ситуация, где уже точно от меня ничего не зависит

_FR>При каких условиях может вылететь исключение в коде

_FR>
_FR>new TcpClient(socket2);
_FR>

_FR> И как ты видишь работу приложения после возникновения OutOfMemory в данном случае? Я вижу только один вариант — перезапуститься. При этом утечек не произойдёт.

_FRED_, ну серьезно, я уже несколько раз написал, как я вижу работу — несколько клиентов отвалилось, остальные счастливо живут. Ну в самом деле, читайте что Вам пишут, ей-богу.

Вы думаете ваш любимый веб-сервер (apache, iis — подставить нужное) перезапускается когда у него возникает OutOfMemory при обработке очередного запроса? И херит при этом все
существующие сессии? Вы бы очень ругались если бы это было так.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[19]: Кошерное использование using
От: _FRED_ Черногория
Дата: 29.06.09 13:01
Оценка:
Здравствуйте, jedi, Вы писали:

J>Это все хорошо если обработка происходит в одном месте. В реальном же приложении, файл открывается и начинается обработка в отдельном потоке. закрыть файл там где его открывали не получится. Ровно то же самое с сокетом в моем изначальном примере.


У меня как-то получалось, наверное я что-то делал неправильно.

_FR>>А ловить OOM на любом new — это паранойя. Если есть метод, который, по спецификации такое может выбросить — ну что ж делать, но ожидать подлянки откуда угодно — глупо, повторю.

J>Я и не предлагал его ловить при каждом new, а всего лишь там где в new передается объект, требующий вызов Dispose.

А в чём разница-то? Вам так же показали ситуацию, при которой вызов Dispose может быть прерван вызовом Thread.Abort(). Как из неё можно было бы выкрутиться и стоит ли вообще пытаться?
Help will always be given at Hogwarts to those who ask for it.
Re[21]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 13:25
Оценка:
Здравствуйте, jedi, Вы писали:

J>Я же предпочитаю подумать 1 раз и пользовать паттерном в следующий раз.

J>Например таким:

J>

J>class Connection
J>{
J>    private Connection(Socket socket)
J>    {
J>        // Perform initialization
J>    }
    
J>    static public Create(Socket socket)
J>    {
J>        try
J>        {
J>            return new Connection(socket);            
J>        }
J>        catch
J>        {
J>            socket.Close();
J>            throw;
J>        }    
J>    }
J>}

J>


J>Вот и все решение поднятой в начале проблемы. Я не понимаю из-за чего поднялся такой вой


А потом после создания экземпляра Connection возникло InvalidOperationException при чтени данных, и ровно такой же катч придется писать и там?

Что-то не тянет это на паттерн.
Re[22]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 13:29
Оценка:
Здравствуйте, samius, Вы писали:

J>>Вот и все решение поднятой в начале проблемы. Я не понимаю из-за чего поднялся такой вой


S>А потом после создания экземпляра Connection возникло InvalidOperationException при чтени данных, и ровно такой же катч придется писать и там?


Он там и так есть, если вы вызываете BeginSend или BeginReceive — это ваша святая обязанность поймать любое неожиданное исключение в обработчике завершения асинхронной операции, залогировать его и закрыть соединение. Иначе будет плохо.

S>Что-то не тянет это на паттерн.


Я никого не уговариваю.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[23]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 13:31
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, samius, Вы писали:


J>>>Вот и все решение поднятой в начале проблемы. Я не понимаю из-за чего поднялся такой вой


S>>А потом после создания экземпляра Connection возникло InvalidOperationException при чтени данных, и ровно такой же катч придется писать и там?


J>Он там и так есть, если вы вызываете BeginSend или BeginReceive — это ваша святая обязанность поймать любое неожиданное исключение в обработчике завершения асинхронной операции, залогировать его и закрыть соединение. Иначе будет плохо.


Именно там это и надо делать, а не в Connection.Create!
Re[24]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 13:39
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, jedi, Вы писали:


J>>Здравствуйте, samius, Вы писали:


J>>>>Вот и все решение поднятой в начале проблемы. Я не понимаю из-за чего поднялся такой вой


S>>>А потом после создания экземпляра Connection возникло InvalidOperationException при чтени данных, и ровно такой же катч придется писать и там?


J>>Он там и так есть, если вы вызываете BeginSend или BeginReceive — это ваша святая обязанность поймать любое неожиданное исключение в обработчике завершения асинхронной операции, залогировать его и закрыть соединение. Иначе будет плохо.


S>Именно там это и надо делать, а не в Connection.Create!


Наша песня хороша начинай сначала ...
Еще раз, до обработчка завершения BeginSend/BeginReceive дело может не дойти если код "new Connection" вызвал OutOfMemoryException.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[25]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 13:50
Оценка:
Здравствуйте, jedi, Вы писали:

J>>>Он там и так есть, если вы вызываете BeginSend или BeginReceive — это ваша святая обязанность поймать любое неожиданное исключение в обработчике завершения асинхронной операции, залогировать его и закрыть соединение. Иначе будет плохо.


S>>Именно там это и надо делать, а не в Connection.Create!


J>Наша песня хороша начинай сначала ...

J>Еще раз, до обработчка завершения BeginSend/BeginReceive дело может не дойти если код "new Connection" вызвал OutOfMemoryException.

Не возникало мысли, что до new Connection дело тоже может не дойти?

Потому код, вызывающий _listener.EndAccept(ar) уже должен быть в блоке try/catch раз на то пошло. Только вот экземпляра сокета catch он не увидит, если пробросило в EndAccept, потому закрытие сокета будет висеть на GC.
Re[26]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 13:54
Оценка:
Здравствуйте, samius, Вы писали:

S>Не возникало мысли, что до new Connection дело тоже может не дойти?


S>Потому код, вызывающий _listener.EndAccept(ar) уже должен быть в блоке try/catch раз на то пошло.


С чего ты решил что это код не в try/catch?

S>Только вот экземпляра сокета catch он не увидит, если пробросило в EndAccept, потому закрытие сокета будет висеть на GC.


Если EndAccept написал так, что бросает исключение не зыкрыв висящий сокет — это очень плохо и минус парням из майкрософт.
Если же до реального вызова accept() в коде EndAccept() не дошло, то сокет останется в ядре либо до следующего вызова accept(),
либо будет закрыт по истечении некоторого таймаута, что меня вполне устраивает. В отличие от ситуации, когда он будет висеть
неопределенно долго до сборки мусора в первом поколении.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[27]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 13:59
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, samius, Вы писали:


S>>Не возникало мысли, что до new Connection дело тоже может не дойти?


S>>Потому код, вызывающий _listener.EndAccept(ar) уже должен быть в блоке try/catch раз на то пошло.


J>С чего ты решил что это код не в try/catch?


С того, что твой паттерн заворачивает конструктор Connection в отдельный try/catch.

S>>Только вот экземпляра сокета catch он не увидит, если пробросило в EndAccept, потому закрытие сокета будет висеть на GC.


J>Если EndAccept написал так, что бросает исключение не зыкрыв висящий сокет — это очень плохо и минус парням из майкрософт.

Сам писал, что речь не только о сокете, что это может быть все что угодно.

J>Если же до реального вызова accept() в коде EndAccept() не дошло, то сокет останется в ядре либо до следующего вызова accept(),

J>либо будет закрыт по истечении некоторого таймаута, что меня вполне устраивает. В отличие от ситуации, когда он будет висеть
Кто сказал, что этот таймаут случится раньше чем сборка в первом поколении?

J>неопределенно долго до сборки мусора в первом поколении.

Откуда уверенность про первое поколение? Может этот сокет уже пережил не одну сборку?
Re[28]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 14:03
Оценка:
Здравствуйте, samius, Вы писали:

J>>С чего ты решил что это код не в try/catch?


S>С того, что твой паттерн заворачивает конструктор Connection в отдельный try/catch.


Я не вижу как одно мешает другому

S>>>Только вот экземпляра сокета catch он не увидит, если пробросило в EndAccept, потому закрытие сокета будет висеть на GC.


J>>Если EndAccept написал так, что бросает исключение не зыкрыв висящий сокет — это очень плохо и минус парням из майкрософт.

S>Сам писал, что речь не только о сокете, что это может быть все что угодно.

Я не вижу здесь противоречия. Покажи.

J>>Если же до реального вызова accept() в коде EndAccept() не дошло, то сокет останется в ядре либо до следующего вызова accept(),

J>>либо будет закрыт по истечении некоторого таймаута, что меня вполне устраивает. В отличие от ситуации, когда он будет висеть
S>Кто сказал, что этот таймаут случится раньше чем сборка в первом поколении?

Таймаут — это нечто определенное, даже если он большой. Сборка мусора — нет.

J>>неопределенно долго до сборки мусора в первом поколении.

S>Откуда уверенность про первое поколение? Может этот сокет уже пережил не одну сборку?

Может. Уверенности нет. Просто объекты с финализатором (коим является SafeHandle сидящий внутри сокета) в нулевом поколении не собираются.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[29]: Кошерное использование using
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.06.09 14:18
Оценка:
Здравствуйте, jedi, Вы писали:

J>Здравствуйте, samius, Вы писали:


J>>>С чего ты решил что это код не в try/catch?


S>>С того, что твой паттерн заворачивает конструктор Connection в отдельный try/catch.


J>Я не вижу как одно мешает другому


Мешать не мешает, но и смысла для заворачивания конструктора класса в отдельный try/catch тоже нет.

J>>>Если EndAccept написал так, что бросает исключение не зыкрыв висящий сокет — это очень плохо и минус парням из майкрософт.

S>>Сам писал, что речь не только о сокете, что это может быть все что угодно.

J>Я не вижу здесь противоречия. Покажи.


Показать код, который не чистит ресурсы в случае исключения, будь то сокет, файл или транзакция?
Даже пробовать не буду.
Re[30]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 14:38
Оценка:
Здравствуйте, samius, Вы писали:

S>Мешать не мешает, но и смысла для заворачивания конструктора класса в отдельный try/catch тоже нет.


Ок, не видишь, так не видишь. Я тут ничем почем не могу.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[13]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 29.06.09 14:38
Оценка:
Здравствуйте, Arboz, Вы писали:

MC>>Может, но исключения OutOfMemoryException, StackOverflowException и ExecutionEngineException не отлавливаются вообще никак, и в этом случае происходит неизбежное закрытие программы.


A>Из приведенных только StackOverflowException обладает подобной особенностью по докам.


По каким докам? Можно ссылку?
Re[14]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 14:40
Оценка:
Здравствуйте, Arboz, Вы писали:

A>Здравствуйте, Arboz, Вы писали:


A>Да... ибо не ввести в заблуждение: OutOfMemoryException, StackOverflowException не CSE-исключения

A>Источник

Нет ли этой доки в человеческом формате? Ибо ставить новый офис нет ни желания, ни возможности. Заранее спасибо!
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[31]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 14:41
Оценка:
J>Ок, не видишь, так не видишь. Я тут ничем помочь не могу.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[14]: Кошерное использование using
От: Arboz Россия  
Дата: 29.06.09 14:43
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>По каким докам? Можно ссылку?


MSDN

Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default.


Про другие два (упомянутые выше) исключения ничего подобного не сказано.
Re[15]: Кошерное использование using
От: Arboz Россия  
Дата: 29.06.09 14:45
Оценка:
Здравствуйте, jedi, Вы писали:

J>Нет ли этой доки в человеческом формате? Ибо ставить новый офис нет ни желания, ни возможности. Заранее спасибо!


По ссылке просто презентация доклада о Framework 4.0,
Основную фразу, в контексте нашего разговора, я оттуда уже привел.
Re[15]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 29.06.09 14:51
Оценка:
Здравствуйте, Arboz, Вы писали:

A>MSDN


A>

A>Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default.


A>Про другие два (упомянутые выше) исключения ничего подобного не сказано.


Если ничего не сказано, это не значит что их всегда можно поймать.
К примеру:
http://bytes.com/groups/net-vb/612133-unhandled-exception-type-system-executionengineexception-occurred-system-data-dll
Re[16]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 14:52
Оценка:
Здравствуйте, Arboz, Вы писали:

A>По ссылке просто презентация доклада о Framework 4.0,

A>Основную фразу, в контексте нашего разговора, я оттуда уже привел.

За это спасибо.
В контексте нашего разговора — как Вы считаете, имеет смысл ли смысл ловить OutOfMemoryException на самом верхнем уровне? В смысле, на уровне соединения в сервере, дабы закрыть его и позволить остальным клиентам обслуживаться нормально? Если да, то есть ли какие-то подводные камни?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[29]: Кошерное использование using
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 29.06.09 15:57
Оценка:
Здравствуйте, jedi, Вы писали:

J>Может. Уверенности нет. Просто объекты с финализатором (коим является SafeHandle сидящий внутри сокета) в нулевом поколении не собираются.


SafeHandle это не просто объект с финализацией, это еще и CriticalFinalizerObject
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
AVK Blog
Re[30]: Кошерное использование using
От: jedi Мухосранск  
Дата: 29.06.09 16:08
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, jedi, Вы писали:


J>>Может. Уверенности нет. Просто объекты с финализатором (коим является SafeHandle сидящий внутри сокета) в нулевом поколении не собираются.


AVK>SafeHandle это не просто объект с финализацией, это еще и CriticalFinalizerObject


Я так понимаю это не отменяет того факта, что он не собирается в нулевом поколении? Или я что-то упустил?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[5]: Кошерное использование using
От: ylem  
Дата: 29.06.09 23:27
Оценка:
Y>>Один хрен, ему дали сокетом попользоваться, а он его прибивает.
TK>А с "гвоздями" такой use-case вас тоже удивляет?

Я не знаю, что такое "гвозди", но если Вы имеете в виду гвозди, то их забивают.

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

TK>Конструктор занимается только инициализацией экземпляра. Никто не запрещает создавать "не инициализированные" экземпляры.

Или Вы не поняли, что я хотел сказать лишь о том, что кто-то содает объект по средствам фабрики (а не фабрика его создает), или я не понял, что хотели сказать Вы.
Может, если сказать, что "фабрика не создает объект, а лишь занимается инициализацией экземпляра (иногда выбирая его конкретный тип)", будет понятней?
Re[5]: Кошерное использование using
От: ylem  
Дата: 29.06.09 23:33
Оценка:
J>Такие примеры в FCL еще есть.

Честно говоря, я не знаю, из каких соображений так сделано. (Вы знаете, зачем?)
Но то, что про эти "особенности" приходится знать, меня напрягает.

Y>>Передавайте коннекшену саму фабрику или на худой конец, "фабричный делегат", если уж всё именно так, как Вы задумали.

J>Зачем такие сложности? Какие я получу от этого преимущества в моем коде?

Не такие уж и сложности. Ваш коннекшн получит единовластное (а не "на правах последнего") пользование коннекшеном, если это Вам действительно нужно.

PS
Я не исключаю, что не улавливаю тонкую разницу между вызовом полноценного деструктора и метода Dispose()
Re[21]: Кошерное использование using
От: Аноним  
Дата: 29.06.09 23:44
Оценка:
Здравствуйте, jedi, Вы писали:

J>Этой ситуации просто не может быть. За мои 10 лет кодирования, я ни разу не применял ни TerminateThread(), ни Thread.Abort() и надеюсь сохранить достаточную трезвость ума, чтоб не применять их и в будущем . Все мои серверные приложения жили (некоторые живут до сих пор) счастливо. Наверное я что-то делал неправильно (с).


вот ты несколькими постами выше писал про синдром "бакалавра"? а за собой сего не замечаешь? цитата выше является классическим образчиком.
где ты был когда "любимая" тобою тема (Thred.Abort) обсуждалась_здесь
Автор:
Дата: 13.03.09
? где те, умные советы которыми стОило поделится?
не поленись, прокомментируй пост
Автор:
Дата: 13.03.09
Re[31]: Кошерное использование using
От: Arboz Россия  
Дата: 30.06.09 06:24
Оценка:
AVK>>SafeHandle это не просто объект с финализацией, это еще и CriticalFinalizerObject

J>Я так понимаю это не отменяет того факта, что он не собирается в нулевом поколении? Или я что-то упустил?


Нет, не отменяет.

Однако есть гарантия, что handle рано или поздно обязательно освободится. В версии Fw 1.1 это не гарантировалось.
Re[32]: Кошерное использование using
От: TK Лес кывт.рф
Дата: 30.06.09 07:16
Оценка:
Здравствуйте, Arboz, Вы писали:

A>Однако есть гарантия, что handle рано или поздно обязательно освободится. В версии Fw 1.1 это не гарантировалось.


У вас какое-то неправильное впечатление об первой версии framework. Финализатор мог не вызваться только некоторых случаях при завершении процесса. CriticalFinalizerObject позволяет обработать лишь некоторые из них. Однако, полной гарантии не дает и он.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[33]: Кошерное использование using
От: Arboz Россия  
Дата: 30.06.09 08:41
Оценка:
Здравствуйте, TK, Вы писали:

TK>Здравствуйте, Arboz, Вы писали:


A>>Однако есть гарантия, что handle рано или поздно обязательно освободится. В версии Fw 1.1 это не гарантировалось.


TK>У вас какое-то неправильное впечатление об первой версии framework. Финализатор мог не вызваться только некоторых случаях при завершении процесса.

Именно это я и имел ввиду.

TK>CriticalFinalizerObject позволяет обработать лишь некоторые из них. Однако, полной гарантии не дает и он.

Можете привести пример, в котором не будет вызван Finalize у SafeHandle.
Re[22]: Кошерное использование using
От: TK Лес кывт.рф
Дата: 30.06.09 08:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>не поленись, прокомментируй пост
Автор:
Дата: 13.03.09


Thread.Abort не будет абортить "зависшие" операции ввода/вывода и unmanaged треды.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[23]: Кошерное использование using
От: Аноним  
Дата: 30.06.09 11:30
Оценка:
Здравствуйте, TK, Вы писали:

TK>Thread.Abort не будет абортить "зависшие" операции ввода/вывода и unmanaged треды.


в курсе, это уже детали. а как быть например с длительными "управляемыми" операциями?
Re[24]: Кошерное использование using
От: TK Лес кывт.рф
Дата: 30.06.09 11:37
Оценка:
Здравствуйте, Аноним, Вы писали:

TK>>Thread.Abort не будет абортить "зависшие" операции ввода/вывода и unmanaged треды.

А>в курсе, это уже детали. а как быть например с длительными "управляемыми" операциями?

Длительные "управляемые" операции надо соответствующим образом проектировать так, что-бы Thread.Abort для их прерывания не требовался. Если же эти операции "падают" с неба то, выносите их в отдельный процесс — потенциальных проблем будет сильно меньше.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[25]: Кошерное использование using
От: Аноним  
Дата: 30.06.09 12:29
Оценка:
Здравствуйте, TK, Вы писали:

TK>Длительные "управляемые" операции надо соответствующим образом проектировать так, что-бы Thread.Abort для их прерывания не требовался. Если же эти операции "падают" с неба то, выносите их в отдельный процесс — потенциальных проблем будет сильно меньше.


вот, оказывается вы невнимательно читали пост, ссылку на который я дал. дам же написано кое-что кроме базы данных — создание отчета. а конкретно Crystal Reports (впрочем неважно). Как предлагаете мне управлять стороенней библиотекой и длительность выполнения операции, в частности создания отчета, которая (операция) может растянутся на минуты?
Re[26]: Кошерное использование using
От: jedi Мухосранск  
Дата: 30.06.09 12:41
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>вот, оказывается вы невнимательно читали пост, ссылку на который я дал. дам же написано кое-что кроме базы данных — создание отчета. а конкретно Crystal Reports (впрочем неважно). Как предлагаете мне управлять стороенней библиотекой и длительность выполнения операции, в частности создания отчета, которая (операция) может растянутся на минуты?


А в чем проблема поместить каждый сервис в отдельный процесс? Оно и понадежней будет — помрет один неожиданно, другие жить останутся.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[27]: Кошерное использование using
От: Аноним  
Дата: 30.06.09 13:19
Оценка:
Здравствуйте, jedi, Вы писали:

J>А в чем проблема поместить каждый сервис в отдельный процесс? Оно и понадежней будет — помрет один неожиданно, другие жить останутся.


ну, их много. для каждого писАть солюшены, запускающее приложение и всю "инфраструктуру" слишком тяжко. тогда как в нынешнем виде вообще все реализовано в виде плагинов, проблему отваливания решаю посредством загрузки каждого сервиса в собственный домен.

з.ы. я считаю, что это распростаненный способ, взгляните хотя бы на svchost и его предназначение, а также сколько сервисов он хостит
Re[28]: Кошерное использование using
От: jedi Мухосранск  
Дата: 30.06.09 13:23
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, jedi, Вы писали:


J>>А в чем проблема поместить каждый сервис в отдельный процесс? Оно и понадежней будет — помрет один неожиданно, другие жить останутся.


А>ну, их много. для каждого писАть солюшены, запускающее приложение и всю "инфраструктуру" слишком тяжко.


Ну это один раз сделать надо, а потом жить счастливо.

А>тогда как в нынешнем виде вообще все реализовано в виде плагинов, проблему отваливания решаю посредством загрузки каждого сервиса в собственный домен.


Странно тогда, что файлы остаются залоченными при выгрузке домена. Как тут уже писали, это CriticalFinalizerObject, он должен почиститься
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[29]: Кошерное использование using
От: Аноним  
Дата: 30.06.09 13:29
Оценка:
Здравствуйте, jedi, Вы писали:

J>Ну это один раз сделать надо, а потом жить счастливо.

.., а потом поддерживать в каждом. да ну нафик такую перспективу.

J>Странно тогда, что файлы остаются залоченными при выгрузке домена. Как тут уже писали, это CriticalFinalizerObject, он должен почиститься


ну на тот момент была не решена, тогда временно сделал через GC.Collect (рабочий вариант кстати), потом плагинную архитектуру реализовал, щас в процессе вндерения "доменности" плагинов

з.ы. вот один фиг, спать не дает Thread.Abort, а ниче не поделаешь
Re[30]: Кошерное использование using
От: jedi Мухосранск  
Дата: 30.06.09 13:43
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>з.ы. вот один фиг, спать не дает Thread.Abort, а ниче не поделаешь


Я с CrystalReport не работал, оно что совсем никак не дает отменить начатую долгую операцию?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[27]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 06.07.09 16:22
Оценка:
Кстати, словил щас OutOfMemoryException из StringBuilder.Append(), поймалось в try-catch без проблем. Все-таки кто-нибудь из местных гуру может точно сказать (ну так, интересно для саморазвития), есть ли ситуации когда OutOfMemoryException не ловится (как StackOverflowException)? Т.е. всё-таки к каким его относить — к отлавливаемым или нет?
Re[6]: Кошерное использование using
От: drol  
Дата: 06.07.09 16:34
Оценка:
Здравствуйте, adontz, Вы писали:

A>Thread.Abort это какой-то экстремальный случай.


Это в теории. А на практике, тот же ASP.NET просто обожает его организовывать.
Re[28]: Кошерное использование using
От: jedi Мухосранск  
Дата: 06.07.09 20:11
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Кстати, словил щас OutOfMemoryException из StringBuilder.Append(), поймалось в try-catch без проблем. Все-таки кто-нибудь из местных гуру может точно сказать (ну так, интересно для саморазвития), есть ли ситуации когда OutOfMemoryException не ловится (как StackOverflowException)? Т.е. всё-таки к каким его относить — к отлавливаемым или нет?


К ошибкам дизайна .NET Они его почему-то бросают и в случае, если jitter-у не хватило памяти на компиляцию метода. Соответственно, ее может не хватить и на компиляцию чего-то вызываемого в catch-блоке. А тогда — повторное исключение и до свидания. Я кстати, не понимаю почему нет возможности заставить рантайм заджитить всю сборку при загрузке (или есть?).

В общем, дело ясное, что дело темное. Лично для меня подобные "тонкости" — это минус дотнету при выборе платформы для очередного проекта (хотя, надо признать, его плюсы в последнее время начинают перевешивать ).
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.