Здравствуйте, Nikolay_P_I, Вы писали:
0K>>А админ как узнает в чем проблема? 2 сообщения нужна: для админа и для пользователя. Там де написано в самом первом посте.
N_P>Потому и полное исключение со стектрейсом. Не поймет админ — позвонит разработчику.
Ну вот. Программа должна работать так, чтобы разработчик мог отдыхать. А если делать по вашей логики -- то разработчик только и будет "на телефоне сидеть". Это главный принцип хорошей программы: программа работает, разработчик отдыхает.
N_P>Просто если к старту юзерской программы к ней должен быть нормальный, существующий и корректно разбирающийся конфиг — не дело юзера разбираться почему даже "file not found", не говоря уж о "ошибка при чтении XML, строка 5, позиция 4" потому как ЛЮБОЙ факт ошибки чтения конфига в такой ситуации свидетельствует о создании нештатной ситуации и неизвестно — чего там еще не так.
Так и нужно писать: файл поврежден, желаете ли создать новый файл?
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, 0K, Вы писали:
0K>>Нет. Если файл не существует -- программа должна его создать. G>Файл будет создан один раз, это можно вынести вне кода, увеличивающего значение счетчика.
Нет, по условию если файла нет -- нужно создать.
G>>>3)Значение счетчика, записанного туда, обязательно корректно 0K>>Я же сказал: этот файл использует другая программа, которую мы не можем изменить. Она работает криво, может чего-то не того записать в файл. G>Ну это уже чушь, если "другая программа" может записать что угодно, то и я могу записать что угодно и не париться по этому поводу.
Опять-таки нет. Чужие ошибки не дают нам права делать плохо.
0K>>>>Покажите нам как эту задачу решить правильно 0K>>Давайте пишите код. Неужели вам не лень базикать и лень писать код? Слова -- ничто, код -- все. G>Мне всегда лень писать код. А если писать, то надо определиться с тем что он делает и не делает.
А комментировать вам не лень? Легче написать несколько строчек, чем читать все это и переливать из пустого в порожнее. Несколько строчек вашего кода могли бы убедить в вашей правоте лучше 100 тыс. слов.
Здравствуйте, 0K, Вы писали:
0K>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, 0K, Вы писали:
0K>>>Нет. Если файл не существует -- программа должна его создать. G>>Файл будет создан один раз, это можно вынести вне кода, увеличивающего значение счетчика.
0K>Нет, по условию если файла нет -- нужно создать.
Если файла нет, то читающая программа в принципе не работает.
G>>>>3)Значение счетчика, записанного туда, обязательно корректно 0K>>>Я же сказал: этот файл использует другая программа, которую мы не можем изменить. Она работает криво, может чего-то не того записать в файл. G>>Ну это уже чушь, если "другая программа" может записать что угодно, то и я могу записать что угодно и не париться по этому поводу.
0K>Опять-таки нет. Чужие ошибки не дают нам права делать плохо.
Не в этом вопрос, а в том что при неизвестной логике "другой программы" делать что-то бессмысленно.
0K>>>>>Покажите нам как эту задачу решить правильно 0K>>>Давайте пишите код. Неужели вам не лень базикать и лень писать код? Слова -- ничто, код -- все. G>>Мне всегда лень писать код. А если писать, то надо определиться с тем что он делает и не делает.
0K>А комментировать вам не лень?
Не-а, потому что обсуждение помогает прийти к тому что на самом деле может понадобиться.
0K>Легче написать несколько строчек, чем читать все это и переливать из пустого в порожнее. Несколько строчек вашего кода могли бы убедить в вашей правоте лучше 100 тыс. слов.
Я думаю тебя они бы ни в чем не убедили, потому что тебе надо не работающую программу получить, а что-то кому-то доказать.
Приведи требования (полные и непротиворчеивые в таком масштабе это просто) и будет тебе программа.
Вкратце ситуация выглядит так: ты приводишь код, который решает непонятно какую задачу и просишь других переписать этот код правильно. Но правильность кода зависит исключительно от задач. А задачу ты формулировать не хочешь, потому что тогда исчезнет твоя цель доказывания чего-то кому-то.
Здравствуйте, gandjustas, Вы писали:
G>Вкратце ситуация выглядит так: ты приводишь код, который решает непонятно какую задачу и просишь других переписать этот код правильно. Но правильность кода зависит исключительно от задач. А задачу ты формулировать не хочешь...
Здравствуйте, GarryIV, Вы писали:
GIV>А если файл находится где то в сети надо выдать сообщение "Проверьте настроки сетевого подключения"?
Нет, надо выдать "Желаете ли проверить настойки сетевого подключения?" И ещё стопятьсот вопросов, потому как диагностика проблем всё ещё является искусством.
Здравствуйте, gandjustas, Вы писали:
0K>>Нет, по условию если файла нет -- нужно создать. G>Если файла нет, то читающая программа в принципе не работает.
Так вот чтобы пользователь не создавал его вручную -- позаботьтесь об этом и создайте файл.
0K>>Опять-таки нет. Чужие ошибки не дают нам права делать плохо. G>Не в этом вопрос, а в том что при неизвестной логике "другой программы" делать что-то бессмысленно.
А зачем вам логика это другой программы? Ваша задача считать из файла число и записать его инкремент. Если файла не существует -- создать. Причем сделать максимально удобно для пользователя (если ошибся пользователь -- внятно пояснить и дать возможность повторить ввод). Если файл будет заблокирован/не доступен и пр -- так-же внятно отобразить сообщения. Неужели это не понятно?
0K>>Легче написать несколько строчек, чем читать все это и переливать из пустого в порожнее. Несколько строчек вашего кода могли бы убедить в вашей правоте лучше 100 тыс. слов. G>Я думаю тебя они бы ни в чем не убедили, потому что тебе надо не работающую программу получить, а что-то кому-то доказать. G>Приведи требования (полные и непротиворчеивые в таком масштабе это просто) и будет тебе программа.
Здравствуйте, GarryIV, Вы писали:
GIV>А если файл находится где то в сети надо выдать сообщение "Проверьте настроки сетевого подключения"?
Зачем? Нет, конечно. Попробуйте одной из MS-овских программ открыть файл из сети с выключенной сетью. Сообщение будет таким же, как если бы файл был на диске.
Здравствуйте, GarryIV, Вы писали:
0K>>Так и нужно писать: файл поврежден, желаете ли создать новый файл?
GIV>А если файл находится где то в сети надо выдать сообщение "Проверьте настроки сетевого подключения"?
Вот именно. Я даже больше скажу — часть исключений вообще нормально не обработать
Так, в данном примере — если кто-то посторонний открыл конфиг на редактирование в блокноте — мы получим при записи в него ошибку "файл занят иным процессом". При этом — это будет самое заурядное "IOException" ничем кроме .Message от прочих не отличающееся. То есть даже захочешь как-то специфически обработать — не выйдет.
Здравствуйте, 0K, Вы писали:
0K>Здравствуйте, gandjustas, Вы писали:
0K>>>Нет, по условию если файла нет -- нужно создать. G>>Если файла нет, то читающая программа в принципе не работает.
0K>Так вот чтобы пользователь не создавал его вручную -- позаботьтесь об этом и создайте файл.
0K>>>Опять-таки нет. Чужие ошибки не дают нам права делать плохо. G>>Не в этом вопрос, а в том что при неизвестной логике "другой программы" делать что-то бессмысленно.
0K>А зачем вам логика это другой программы? Ваша задача считать из файла число и записать его инкремент. Если файла не существует -- создать. Причем сделать максимально удобно для пользователя (если ошибся пользователь -- внятно пояснить и дать возможность повторить ввод). Если файл будет заблокирован/не доступен и пр -- так-же внятно отобразить сообщения. Неужели это не понятно?
0K>>>Легче написать несколько строчек, чем читать все это и переливать из пустого в порожнее. Несколько строчек вашего кода могли бы убедить в вашей правоте лучше 100 тыс. слов. G>>Я думаю тебя они бы ни в чем не убедили, потому что тебе надо не работающую программу получить, а что-то кому-то доказать. G>>Приведи требования (полные и непротиворчеивые в таком масштабе это просто) и будет тебе программа.
0K>Выше еще раз написал.
Ну хватит уже жопой играть.
Давай сначала
Программа должна быть не демо, а реальной. Т.е. считайте что вы пишите реальный проект, которым будут пользоваться тысячи людей.
Есть какая-то "другая программа", про которую известно что она читает число из файла (как минимум по известному пути), при чтении "другая программа" блокирует файл (видимо писал её какой-то мудак).
Нужна утилита, которая будет увеличивать число в этом файле на единицу. Пользователем будет видимо IT специалист, который немного понимает в компьютерах и причинах сбоя, а также умеет гуглить. Программа будет запускаться в одном экземпляре в одно время.
Идеальный вариант здесь — тн Unix way, консольная программа, которая не требует участия пользователя при запуске, в случае успеха она просто прекращает работу, в случае неудачи выводит информацию об ошибке и завершается с errorlevel отличным от нуля.
Так как заданный файл создается один раз, то проще попросить админа создать его при установке программы, также позаботиться о необходимых правах.
код:
class Program
{
static void Main()
{
var filename = ConfigurationManager.AppSettings["FileName"];
var count = int.Parse(File.ReadAllText(filename)) + 1;
File.WriteAllText(filename, count.ToString());
}
}
Собственно все. Инфу об ошибке и errorlevel отличный от 0 обеспечит встроенный механизм unhandled exception.
Здравствуйте, 0K, Вы писали:
N_P>>Просто если к старту юзерской программы к ней должен быть нормальный, существующий и корректно разбирающийся конфиг — не дело юзера разбираться почему даже "file not found", не говоря уж о "ошибка при чтении XML, строка 5, позиция 4" потому как ЛЮБОЙ факт ошибки чтения конфига в такой ситуации свидетельствует о создании нештатной ситуации и неизвестно — чего там еще не так.
0K>Так и нужно писать: файл поврежден, желаете ли создать новый файл?
А права у него на это есть — создавать файлы ? А иной информации в этих файлах не содержится ? Это навскидку — что у нас с таким подходом вылезет. А еще сеть может отвалиться на минутку и надо-бы попробовать раз 5 повторить чтение с задержкой.
Здравствуйте, Muxa, Вы писали:
M>поменьше слов, побольше кода. (c)
У меня вопросы по этому участку кода
try {
using (StreamReader reader = _fileInfo.OpenText()) {
if (!int.TryParse(reader.ReadToEnd(), out _value))
_messanger.WriteLine("Файл '{0}' поврежден. Значение счетчика сброшено.", _fileInfo.FullName);
reader.Close();
}
return;
}
catch (FileNotFoundException) {
_messanger.WriteLine("Файл '{0}' не найден и будет создан.", _fileInfo.FullName);
}
1. почему вы обещаете (через messenger) вещи, которые не делаете? Мне лень тестить, но по-моему вы не сбрасываете счётчик (остаётся предыдущее значение, нет?) да и файл вы создаёте в другом методе и по другому признаку. Т.е. например если моя реализация messenger'а выдаст здесь
_messanger.WriteLine("Файл '{0}' поврежден. Значение счетчика сброшено.", _fileInfo.FullName);
FileNotFoundException, то вы пообещаете создать файл, а на самом деле:
if (!_fileInfo.Exists)
using (FileStream stream = _fileInfo.Create()) stream.Close()
обманываете и не пытаетесь его создать. Моя реализация messenger'а может ведь писать в файл внутри WriteLine.
2. вы реально замарачиваетесь в своих проектах и инжектите такой messenger в каждый свой класс? или просто для примера сделали?
N>1. почему вы обещаете (через messenger) вещи, которые не делаете? Мне лень тестить, но по-моему вы не сбрасываете счётчик (остаётся предыдущее значение, нет?)
на счет сброса — дельное замечание. не проследил.
N>да и файл вы создаёте в другом методе и по другому признаку. Т.е. например если моя реализация messenger'а выдаст здесь
N> _messanger.WriteLine("Файл '{0}' поврежден. Значение счетчика сброшено.", _fileInfo.FullName);
N>
N>FileNotFoundException, то вы пообещаете создать файл, а на самом деле: N>
N> if (!_fileInfo.Exists)
N> using (FileStream stream = _fileInfo.Create()) stream.Close()
N>
N>обманываете и не пытаетесь его создать. Моя реализация messenger'а может ведь писать в файл внутри WriteLine.
тогда FileNotFoundException должен быть обработан внутри мессенжера и обернут в MessangerException, ящитаю. не?
(по крайней мере я бы так реализовал этого файлового мессенжера)
а тот FileNotFoundException вылетевший из reader = _fileInfo.OpenText(), просто проглатывается и об отсутствии файл сообщает пользователю, если пользователь попытается записать состояние счетчика, вот тут файл и будет создан. (а то вдруг пользователь передумает).
N>2. вы реально замарачиваетесь в своих проектах и инжектите такой messenger в каждый свой класс? или просто для примера сделали?
нет, конечно.
просто ТС, хотел абстрагированности от консольного применения и портабельности на WinForms и пр.
я предоставил ему необходимые интерфейсы.
G>class Program
G>{
G> static void Main()
G> {
G> var filename = ConfigurationManager.AppSettings["FileName"];
G> var count = int.Parse(File.ReadAllText(filename)) + 1;
G> File.WriteAllText(filename, count.ToString());
G> }
G>}
G>
G>Собственно все. Инфу об ошибке и errorlevel отличный от 0 обеспечит встроенный механизм unhandled exception.
Вы приходите на форум потоллить? Или как это понимать? Вы же больше всех выступали, что инфа в полях Exception не предназначена для пользователя (прямого вывода). А теперь сами вывели пользователю только системную информацию.
Задание вы не выпонили: требовалось запрашивать у пользователя имя счетчика (создавать если его нет) и требовалась возможность задейстовавать код в Win-приложении.
Ваш код не переносим, не юзабелен, вместо ошибок выводит непонятную простому пользователю абракадабру.
Ну и самое главное -- вы сами себе противоречите (на счет информации, выводимой пользователю).
Здравствуйте, 0K, Вы писали:
0K>Здравствуйте, gandjustas, Вы писали:
G>>
G>>class Program
G>>{
G>> static void Main()
G>> {
G>> var filename = ConfigurationManager.AppSettings["FileName"];
G>> var count = int.Parse(File.ReadAllText(filename)) + 1;
G>> File.WriteAllText(filename, count.ToString());
G>> }
G>>}
G>>
G>>Собственно все. Инфу об ошибке и errorlevel отличный от 0 обеспечит встроенный механизм unhandled exception.
0K>Вы приходите на форум потоллить? Или как это понимать? Вы же больше всех выступали, что инфа в полях Exception не предназначена для пользователя (прямого вывода). А теперь сами вывели пользователю только системную информацию.
Я вроде подробно описал юзкейсы. То что выводится — информация не для пользователя, а для админа. Для пользователя выводится ровно ничего.
0K>Задание вы не выпонили: требовалось запрашивать у пользователя имя счетчика (создавать если его нет) и требовалась возможность задейстовавать код в Win-приложении.
Нивопрос, давай свои юзкейсы, только чтобы они были риальными, мы же риальное приложение пишем
0K>Ваш код не переносим, не юзабелен, вместо ошибок выводит непонятную простому пользователю абракадабру.
Непереносим куда? Неюзабелен почему?
Ты прочитал описание? Для unix-way он более чем юзабелен и вроде как под моно должен отрабатывать.
0K>Ну и самое главное -- вы сами себе противоречите (на счет информации, выводимой пользователю).
Еще раз, в этом варианте вообще нет взаимодействия с пользователем. Так работают чет более чем все консольные утилиты в *nix.
Здравствуйте, Neco, Вы писали:
N>не согласен. я не отменяю исключения (не гашу их) — просто дополняю информацией. N>
N># It circumvents higher-level exception handling.
N>это с одной стороны звучит убедительно. но с другой стороны — на фига вышестоящему классу заботиться о моих ошибках? сейчас я работаю с файловой системой, а завтра изменю реализацию и буду работать с сокетами (т.е. опять же с инкрменентной целью, но уже по сети). а послезавтра меня осенит, что инкрементность можно возложить на оракл и просто брать оттуда значение следующего сиквенса
Не совсем так. Данная рекомендация говорит, что ты обрабатываешь все ошибки, которые могут возникнуть в твоем коде при нормальной работе и неизменными пробрасываешь дальше те ошибки, которые не относятся к собственно решаемой задаче.
То есть, у тебя явно тут вырисовываются исключения
1. формат числа (включая переполнение)
2. отсутствие файла
3. отсутсвие прав на изменение файла
4. отсутствие прав на добавление файлов в папку с файлами
5. Переполнение 32-битного числа счетчика при инкрементации.
Вот их надо отловить и завернуть в твой IncrementorException. В идеале с уточняющими полями, что именно было не так и с тем чтобы дальше иметь возможность показать пользователю сообщение различного вида в зависимости от проблемы.
А при переходе на сокеты или оракл — надо соответственно обдумать какие теперь могут возникать ошибки и отлавливать теперь уже их.
А например ThreadAbortException ловить и заворачивать в твое IncrementorException не стоит. А ведь вполне возможно, что этот инкрементатор будут запускать в отдельном потоке.
Так же, если ты действительно перейдешь на работу с Ораклом, причем на удаленном сервере — то получив сверху открытый коннекшен ты можешь предполагать, что он в процессе работы инкрементора он все время будет валидным, поскольку управление коннекшеном (если его передали сверху) не лежит в области ответственности инкрементора. А значит, не надо и пытаться обрабатывать ситуации с оторванным в процесе работы сетевым шнурком — эта обработка находится на уровень выше.
А вот исключение, что твой инкрементальный сиквенс отсутсвтует или уже переполнился — тебе надо отловить и обработать.
Здравствуйте, fmiracle, Вы писали:
F>Вот их надо отловить и завернуть в твой IncrementorException. В идеале с уточняющими полями, что именно было не так и с тем чтобы дальше иметь возможность показать пользователю сообщение различного вида в зависимости от проблемы.
Ага. Что-то начинаю понимать, но для полной ясности мне надо понять, что должен делать с этим вышестоящий класс. Не мог бы ты описать или пример привести?