Здравствуйте, MozgC, Вы писали:
MC>Здравствуйте, jedi, Вы писали:
J>>Если вы почитаете ветку выше, я привел один-в-один такой же код. J>>В целом он меня устраивает. Я всего лишь пытался узнать есть ли какие-то штатные методы/паттерны для этой ситуации (я в .NET недавно).
MC>Нет, это не "один-в-один такой же код". В вашем случае такую конструкцию нужно будет писать в каждом месте создания объекта Connection. В моем варианте — нет.
Да, извините, бегло смотрел. Ваш код не гарантирует очистки в случае исключения в точке (1). Хотя, я понял, вы считаете это не нужно. А я считаю нужно. Давайте на этом и разойдемся, а то так можно долго спорить
Здравствуйте, jedi, Вы писали:
J>Да, извините, бегло смотрел. Ваш код не гарантирует очистки в случае исключения в точке (1). Хотя, я понял, вы считаете это не нужно. А я считаю нужно. Давайте на этом и разойдемся, а то так можно долго спорить
Вы опять невнимательно смотрели Мой код гарантирует очистку в случае исключения в точке 1.
Здравствуйте, jedi, Вы писали:
J>При чем здесь сбой в оперативной памяти? J>Банально — пытались записать в ивент лог, что принято новое соединения, произошло исключение — не хватило прав. Все, пусть сокет висит?
Ну а запись в эвент-лог где, в точке №1? Тогда это просто не правильно
J>Я понимаю, что сборщик мусора все это когда-то вычистит. Но для 24/7 приложения это не годится.
Так, стоп. Сборщик мусора как раз для 24/7 приложения существует. Лучше почистить когда-то, чем вообще никогда.
J>Я всего лишь спросил, как принято поступать в таких ситуациях. Вы же принялись убеждать, что все это фигня, думать об этом не нужно и сбрщик мусора когда-то почистит.
Вот именно, думать об этом не нужно. Вы никогда не сможете обработать все возможные сбои, поэтому займитесь актуальными. Сбой инициализации стека метода и сбой оператора присваивания настолько маловероятны, что на них вообще не стоит тратить время.
Здравствуйте, jedi, Вы писали:
J>Здравствуйте, MozgC, Вы писали:
MC>>Здравствуйте, jedi, Вы писали:
J>>>Если вы почитаете ветку выше, я привел один-в-один такой же код. J>>>В целом он меня устраивает. Я всего лишь пытался узнать есть ли какие-то штатные методы/паттерны для этой ситуации (я в .NET недавно).
MC>>Нет, это не "один-в-один такой же код". В вашем случае такую конструкцию нужно будет писать в каждом месте создания объекта Connection. В моем варианте — нет.
J>Да, извините, бегло смотрел. Ваш код не гарантирует очистки в случае исключения в точке (1). Хотя, я понял, вы считаете это не нужно. А я считаю нужно. Давайте на этом и разойдемся, а то так можно долго спорить
P.S. Точка (1) может быть и не в конструкторе, а например в конструкторе базового типа.
В общем, подумав соглашусь в такой формулировке:
1) класс Connection должен гарантировать, что исключения не будет до строки _socket = socket.
2) Если исключение будет после, он обязан его поймать и сокет закрыть, исключение перебросить.
3) Если возникает OutOfMemoryException например при попытке выделения памяти под Connection — все равно мы уже ничего сделать не можем и надо потушить свет.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, jedi, Вы писали:
J>>При чем здесь сбой в оперативной памяти? J>>Банально — пытались записать в ивент лог, что принято новое соединения, произошло исключение — не хватило прав. Все, пусть сокет висит?
A>Ну а запись в эвент-лог где, в точке №1? Тогда это просто не правильно
J>>Я понимаю, что сборщик мусора все это когда-то вычистит. Но для 24/7 приложения это не годится.
A>Так, стоп. Сборщик мусора как раз для 24/7 приложения существует. Лучше почистить когда-то, чем вообще никогда.
J>>Я всего лишь спросил, как принято поступать в таких ситуациях. Вы же принялись убеждать, что все это фигня, думать об этом не нужно и сбрщик мусора когда-то почистит.
A>Вот именно, думать об этом не нужно. Вы никогда не сможете обработать все возможные сбои, поэтому займитесь актуальными. Сбой инициализации стека метода и сбой оператора присваивания настолько маловероятны, что на них вообще не стоит тратить время.
Есть еще MemoryOverflowException ... Но тот же Рихтер пишет что это попа и обрабытывать его бессмысленно.
В общем, Вы наверное правы, спасибо
Вы бы привели тогда реальный пример. А то вам отвечаешь — а вы начинаете придумывать какие-то ситуации (которых по вашему конкретному примеру не может быть) на ходу.
Здравствуйте, MozgC, Вы писали:
MC>Вы бы привели тогда реальный пример. А то вам отвечаешь — а вы начинаете придумывать какие-то ситуации (которых по вашему конкретному примеру не может быть) на ходу.
Что значит не может быть?
По-Вашему эта строка:
new Connection(socket);
не может вызвать OutOfMemoryException? Другой вопрос, что, как справедливо заметил adontz, это обрабатывать не надо.
P.S. Не спорьте больше, я и с Вами и с adontz-ем согласился. Спасибо.
Здравствуйте, jedi, Вы писали:
J>Здравствуйте, MozgC, Вы писали:
MC>>Вы бы привели тогда реальный пример. А то вам отвечаешь — а вы начинаете придумывать какие-то ситуации (которых по вашему конкретному примеру не может быть) на ходу.
J>Что значит не может быть?
Значит что, например, в вашем примере нет базового класса с конструктором.
J>По-Вашему эта строка:
J>
J>new Connection(socket);
J>
J>не может вызвать OutOfMemoryException? Другой вопрос, что, как справедливо заметил adontz, это обрабатывать не надо.
Может, но исключения OutOfMemoryException, StackOverflowException и ExecutionEngineException не отлавливаются вообще никак, и в этом случае происходит неизбежное закрытие программы.
J>P.S. Не спорьте больше, я и с Вами и с adontz-ем согласился. Спасибо.
Не за что
Здравствуйте, 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");
}
}
}
}
}
Здравствуйте, jedi, Вы писали:
J>Кстати. Я тоже об этом читал у товарища Рихтера. J>Но вот это: J>Прекрасно работает. Кому верить?
В данном примере верить вам. Я тоже не раз читал что это исключения нельзя остановить. Может в некоторых ситуациях OutOfMemoryException не может быть поймано, а в некоторых (как в вашем примере) — может. Т.е. возможно это зависит от того при каких условиях CLR выбрасывает это исключение. Хз
Кстаи, можно ссылку на Рихтера об этом исключении? а то в его книге я не нашел где он такое пишет.
Здравствуйте, jedi, Вы писали:
J>Здравствуйте, Lloyd, Вы писали:
L>>Здравствуйте, jedi, Вы писали:
J>>>Внимание, вопрос. Как это кошерно обработать?
L>>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.
J>Я обеими руками за. Только вот не вижу как это применить в данной ситуации
Как вариант: передавать в конструктор не сокет, а номер порта, а сокет создавать в конструкторе.
Здравствуйте, MozgC, Вы писали:
MC>В данном примере верить вам. Я тоже не раз читал что это исключения нельзя остановить. Может в некоторых ситуациях OutOfMemoryException не может быть поймано, а в некоторых (как в вашем примере) — может. Т.е. возможно это зависит от того при каких условиях CLR выбрасывает это исключение. Хз
Ну тогда мы и в исходном примере можем обработать это исключение, закрыть сокет и позволить подключившимся клиентам нормально работать. Даже если какому то из них не хватит памяти — помрет только это соединение, остальные останутся жить, сервер продолжит работу. Что нам и нужно.
MC>Кстаи, можно ссылку на Рихтера об этом исключении? а то в его книге я не нашел где он такое пишет.
Сейчас быстро посмотрел в книге, тоже не смог найти. Возможно я что-то путаю, и это был не Рихтер. Но что-то в таком духе я оперделенно читал Если вспомню/найду, обязательно отпишусь.
Здравствуйте, anton_t, Вы писали:
J>>Я обеими руками за. Только вот не вижу как это применить в данной ситуации
_>Как вариант: передавать в конструктор не сокет, а номер порта, а сокет создавать в конструкторе.
Здравствуйте, jedi, Вы писали:
J>Здравствуйте, anton_t, Вы писали:
J>>>Я обеими руками за. Только вот не вижу как это применить в данной ситуации
_>>Как вариант: передавать в конструктор не сокет, а номер порта, а сокет создавать в конструкторе.
J>
J>>Где Вы здесь увидели номер порта?
_>Вы сказали, что не знаете, как применить здесь принцип "кто создаёт объект, тот его уничтожает", я привёл вариант. Какие-то проблемы с этим?
Не хамите. Если уж беретесь что-то советовать, то хотя бы посмотрите на код, который я привел в самом первом сообщении и повторил специально для Вас. Где Вы там видите номер порта?
J>>>Где Вы здесь увидели номер порта?
_>>Вы сказали, что не знаете, как применить здесь принцип "кто создаёт объект, тот его уничтожает", я привёл вариант. Какие-то проблемы с этим?
J>Не хамите. Если уж беретесь что-то советовать, то хотя бы посмотрите на код, который я привел в самом первом сообщении и повторил специально для Вас. Где Вы там видите номер порта?
Прежде всего
Где Вы здесь увидели номер порта?
мало походит на вежливое обращение, так что замечаем брёвнышки сначала в своём глазу.
По теме: вы не сказали, насколько вы можете поменять свой код, а я не телепат. Не нужны советы — воля ваша .
мало походит на вежливое обращение, так что замечаем брёвнышки сначала в своём глазу.
Извините, но если Вы не удосужились прочитать вопрос и понять код в нем приведенный — зачем что-то отвечать?
_>По теме: вы не сказали, насколько вы можете поменять свой код, а я не телепат. Не нужны советы — воля ваша .
Здравствуйте, Lloyd, Вы писали:
J>>Внимание, вопрос. Как это кошерно обработать? L>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.
А если удариться в специфику то, создает обычно фабрика, а управляет владелец. И в большинстве случаев, это не брат и сестра, а два разных человека.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, jedi, Вы писали:
J>Я понимаю, что сборщик мусора все это когда-то вычистит. Но для 24/7 приложения это не годится. J>Я всего лишь спросил, как принято поступать в таких ситуациях. Вы же принялись убеждать, что все это фигня, думать об этом не нужно и сбрщик мусора когда-то почистит.
Ваше 24/7 приложение это прокат авто или такси? Если такси то, не пускайте клиентов за руль, а если прокат то, в случае аврии — вызывайте страховую...
В приложении это может быть так, что в одном случае клиенту дается не сокет, а некий высокоуровневый "connection" который, абстрагирует используемый ресурс. либо, клиент выносится в отдельный домен/процесс и в случае проблем он банально выгружается вместе со его всеми сокетами...
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, jedi, Вы писали:
J>Банально — пытались записать в ивент лог, что принято новое соединения, произошло исключение — не хватило прав. Все, пусть сокет висит?
Слой логгирования не должен кидать исключений при записи в лог. Никаких. Он вообще должен быть максимально незаметен для кода приложения, а обработка его исключений нарушает это правило.